Dreamine.MVVM.Locators.Wpf 1.0.7
Dreamine.MVVM.Locators.Wpf 사용자 인터페이스 기능과 구성 요소를 제공합니다.
로딩중...
검색중...
일치하는것 없음
RegionBinder.cs
이 파일의 문서화 페이지로 가기
1using System;
2using System.Collections.Generic;
3using System.Diagnostics.CodeAnalysis;
4using System.Windows;
5using System.Windows.Controls;
6
8{
17 public static class RegionBinder
18 {
27 private static readonly object SyncRoot = new();
36 private static readonly Dictionary<string, WeakReference<ContentControl>> RegionMap = new();
37
46 public static readonly DependencyProperty RegionNameProperty =
47 DependencyProperty.RegisterAttached(
48 "RegionName",
49 typeof(string),
50 typeof(RegionBinder),
51 new PropertyMetadata(null, OnRegionNameChanged));
52
77 public static void SetRegionName(DependencyObject obj, string? value)
78 {
79 obj.SetValue(RegionNameProperty, value);
80 }
81
106 public static string? GetRegionName(DependencyObject obj)
107 {
108 return (string?)obj.GetValue(RegionNameProperty);
109 }
110
151 public static void Navigate(string regionName, object viewModel)
152 {
153 if (string.IsNullOrWhiteSpace(regionName))
154 {
155 throw new ArgumentException("Region name must not be empty.", nameof(regionName));
156 }
157
158 if (!TryGetRegion(regionName, out ContentControl? control))
159 {
160 throw new InvalidOperationException($"Region \"{regionName}\" is not registered.");
161 }
162
163 var view = ViewModelBinder.ResolveView(viewModel);
164 control.Content = view;
165 }
166
175 public static void Clear()
176 {
177 lock (SyncRoot)
178 {
179 RegionMap.Clear();
180 }
181 }
182
207 private static void OnRegionNameChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
208 {
209 if (d is not ContentControl control)
210 {
211 return;
212 }
213
214 if (e.OldValue is string oldName)
215 {
216 Unregister(oldName, control);
217 }
218
219 control.Loaded -= OnRegionLoaded;
220 control.Unloaded -= OnRegionUnloaded;
221
222 if (e.NewValue is string name && !string.IsNullOrWhiteSpace(name))
223 {
224 Register(name, control);
225 control.Loaded += OnRegionLoaded;
226 control.Unloaded += OnRegionUnloaded;
227 }
228 }
229
254 private static void OnRegionLoaded(object sender, RoutedEventArgs e)
255 {
256 if (sender is ContentControl control)
257 {
258 string? regionName = GetRegionName(control);
259 if (!string.IsNullOrWhiteSpace(regionName))
260 {
261 Register(regionName, control);
262 }
263 }
264 }
265
290 private static void OnRegionUnloaded(object sender, RoutedEventArgs e)
291 {
292 if (sender is ContentControl control)
293 {
294 string? regionName = GetRegionName(control);
295 if (!string.IsNullOrWhiteSpace(regionName))
296 {
297 Unregister(regionName, control);
298 }
299 }
300 }
301
326 private static void Register(string regionName, ContentControl control)
327 {
328 lock (SyncRoot)
329 {
330 RegionMap[regionName] = new WeakReference<ContentControl>(control);
331 }
332 }
333
358 private static void Unregister(string regionName, ContentControl control)
359 {
360 lock (SyncRoot)
361 {
362 if (RegionMap.TryGetValue(regionName, out WeakReference<ContentControl>? reference) &&
363 reference.TryGetTarget(out ContentControl? registeredControl) &&
364 ReferenceEquals(registeredControl, control))
365 {
366 RegionMap.Remove(regionName);
367 }
368 }
369 }
370
403 private static bool TryGetRegion(string regionName, [NotNullWhen(true)] out ContentControl? control)
404 {
405 lock (SyncRoot)
406 {
407 if (!RegionMap.TryGetValue(regionName, out WeakReference<ContentControl>? reference))
408 {
409 control = null;
410 return false;
411 }
412
413 if (reference.TryGetTarget(out control))
414 {
415 return true;
416 }
417
418 RegionMap.Remove(regionName);
419 control = null;
420 return false;
421 }
422 }
423 }
424}
static void Unregister(string regionName, ContentControl control)
static void SetRegionName(DependencyObject obj, string? value)
static void OnRegionUnloaded(object sender, RoutedEventArgs e)
static void OnRegionLoaded(object sender, RoutedEventArgs e)
static void OnRegionNameChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
static bool TryGetRegion(string regionName, [NotNullWhen(true)] out ContentControl? control)
static void Register(string regionName, ContentControl control)
static void Navigate(string regionName, object viewModel)
static ? string GetRegionName(DependencyObject obj)
static readonly Dictionary< string, WeakReference< ContentControl > > RegionMap
static readonly DependencyProperty RegionNameProperty
static FrameworkElement ResolveView(object viewModel)