Dreamine.UI.Wpf.Controls 1.0.1
Dreamine.UI.Wpf.Controls 사용자 인터페이스 기능과 구성 요소를 제공합니다.
로딩중...
검색중...
일치하는것 없음
DreamineControl.cs
이 파일의 문서화 페이지로 가기
1// ============================================================================
2// \file DreamineTabHost.SingleFile.cs
3// \brief DreamineTabHost + DreamineTabHostItem (single-file copy/paste version)
4// \details
5// - Allows XAML usage like:
6// <vs:DreamineTabHost>
7// <vs:DreamineTabHostItem Content="UiComponentDashboard"/>
8// <vs:DreamineTabHostItem Content="LocalizationDashboard"/>
9// </vs:DreamineTabHost>
10// - Achieved via [ContentProperty(nameof(Items))] so children go into Items,
11// not into Content (avoids "Content set more than once").
12// - Still supports ContentList / ContentTypeList DP-based inputs.
13// - Runtime view loading uses ViewLoader.LoadViewWithViewModel(...).
14// - Popup naming convention: "*_Popup".
15// - Visibility notification to root DataContext via IVisibilityAware.
16// \date 2026-02-12
17// ============================================================================
18
19using System;
20using System.Collections.Generic;
21using System.Collections.ObjectModel;
22using System.ComponentModel;
23using System.Linq;
24using System.Windows;
25using System.Windows.Controls;
26using System.Windows.Markup;
27using System.Windows.Threading;
28using Dreamine.MVVM.Core;
29using Dreamine.MVVM.Interfaces;
31
33{
60 [ContentProperty(nameof(Items))]
61 public class DreamineTabHost : ContentControl
62 {
75 public ObservableCollection<DreamineTabHostItem> Items { get; } = new ObservableCollection<DreamineTabHostItem>();
76
85 private FrameworkElement? _currentView;
86
95 private readonly Dictionary<string, FrameworkElement> _views = new Dictionary<string, FrameworkElement>();
96
105 private readonly List<string> _order = new List<string>();
106
116
126
135 private Grid _containerGrid = null!;
136
145 private bool _isSwitchScheduled;
146
155 private int _designLastIndex = -1;
156
165 private readonly Dictionary<FrameworkElement, bool> _lastVisibilityState = new Dictionary<FrameworkElement, bool>();
166
167 #region ===== Popup awareness: Flag DP & Readonly DP =====
168
177 public static readonly DependencyProperty TargetAnalyzedProperty =
178 DependencyProperty.Register(
179 nameof(TargetAnalyzed),
180 typeof(bool),
181 typeof(DreamineTabHost),
182 new PropertyMetadata(false));
183
192 public bool TargetAnalyzed
193 {
194 get => (bool)GetValue(TargetAnalyzedProperty);
195 set => SetValue(TargetAnalyzedProperty, value);
196 }
197
206 private static readonly DependencyPropertyKey IsCurrentTargetPopupPropertyKey =
207 DependencyProperty.RegisterReadOnly(
208 nameof(IsCurrentTargetPopup),
209 typeof(bool),
210 typeof(DreamineTabHost),
211 new PropertyMetadata(false));
212
221 public static readonly DependencyProperty IsCurrentTargetPopupProperty =
222 IsCurrentTargetPopupPropertyKey.DependencyProperty;
223
233 {
234 get => (bool)GetValue(IsCurrentTargetPopupProperty);
235 private set => SetValue(IsCurrentTargetPopupPropertyKey, value);
236 }
237
238 #endregion
239
249 {
250 // \brief Keep default DP collections alive
251 ContentList = new ObservableCollection<string>();
252
253 // \brief When XAML children change, re-init
254 Items.CollectionChanged += (_, __) => TryInitViews();
255 }
256
257 // =====================================================================
258 // Dependency Properties (Public)
259 // =====================================================================
260
269 public static readonly DependencyProperty ContentListProperty =
270 DependencyProperty.Register(
271 nameof(ContentList),
272 typeof(ObservableCollection<string>),
273 typeof(DreamineTabHost),
274 new PropertyMetadata(new ObservableCollection<string>(), OnContentInputsChanged));
275
287 public ObservableCollection<string> ContentList
288 {
289 get => (ObservableCollection<string>)GetValue(ContentListProperty);
290 set => SetValue(ContentListProperty, value);
291 }
292
301 public static readonly DependencyProperty ContentTypeListProperty =
302 DependencyProperty.Register(
303 nameof(ContentTypeList),
304 typeof(ObservableCollection<string>),
305 typeof(DreamineTabHost),
306 new PropertyMetadata(null, OnContentInputsChanged));
307
316 public ObservableCollection<string> ContentTypeList
317 {
318 get => (ObservableCollection<string>)GetValue(ContentTypeListProperty);
319 set => SetValue(ContentTypeListProperty, value);
320 }
321
330 public static readonly DependencyProperty CurrentViewProperty =
331 DependencyProperty.Register(
332 nameof(CurrentView),
333 typeof(string),
334 typeof(DreamineTabHost),
335 new PropertyMetadata(string.Empty, OnCurrentViewChanged));
336
345 public string CurrentView
346 {
347 get => (string)GetValue(CurrentViewProperty);
348 set => SetValue(CurrentViewProperty, value);
349 }
350
359 public static readonly DependencyProperty SelectViewProperty =
360 DependencyProperty.Register(
361 nameof(SelectView),
362 typeof(int),
363 typeof(DreamineTabHost),
364 new PropertyMetadata(0, OnSelectViewChanged));
365
374 public int SelectView
375 {
376 get => (int)GetValue(SelectViewProperty);
377 set => SetValue(SelectViewProperty, value);
378 }
379
388 public static readonly DependencyProperty UseSingletonViewProperty =
389 DependencyProperty.Register(
390 nameof(UseSingletonView),
391 typeof(bool),
392 typeof(DreamineTabHost),
393 new PropertyMetadata(true, OnContentInputsChanged));
394
404 {
405 get => (bool)GetValue(UseSingletonViewProperty);
406 set => SetValue(UseSingletonViewProperty, value);
407 }
408
409 // ----- Design hints -----
410
419 public static readonly DependencyProperty DesignBaseNamespaceHintProperty =
420 DependencyProperty.Register(
422 typeof(string),
423 typeof(DreamineTabHost),
424 new PropertyMetadata(string.Empty, OnDesignHintChanged));
425
435 {
436 get => (string)GetValue(DesignBaseNamespaceHintProperty);
437 set => SetValue(DesignBaseNamespaceHintProperty, value);
438 }
439
448 public static readonly DependencyProperty DesignAssemblyHintProperty =
449 DependencyProperty.Register(
450 nameof(DesignAssemblyHint),
451 typeof(string),
452 typeof(DreamineTabHost),
453 new PropertyMetadata(string.Empty, OnDesignHintChanged));
454
463 public string DesignAssemblyHint
464 {
465 get => (string)GetValue(DesignAssemblyHintProperty);
466 set => SetValue(DesignAssemblyHintProperty, value);
467 }
468
477 public static readonly DependencyProperty AutoWireDesignViewModelProperty =
478 DependencyProperty.Register(
480 typeof(bool),
481 typeof(DreamineTabHost),
482 new PropertyMetadata(true, OnDesignHintChanged));
483
493 {
494 get => (bool)GetValue(AutoWireDesignViewModelProperty);
495 set => SetValue(AutoWireDesignViewModelProperty, value);
496 }
497
498 // =====================================================================
499 // DP Callbacks
500 // =====================================================================
501
526 private static void OnContentInputsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
527 {
528 if (d is DreamineTabHost c)
529 {
530 c.TryInitViews();
531 }
532 }
533
558 private static void OnDesignHintChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
559 {
560 if (d is DreamineTabHost c && c.IsInDesignMode())
561 {
562 c.TryInitViews();
563 }
564 }
565
590 private static void OnCurrentViewChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
591 {
592 if (d is DreamineTabHost ctrl && e.NewValue is string viewName)
593 {
594 ctrl.Dispatcher.BeginInvoke(new Action(() =>
595 {
596 ctrl.SwitchToViewInternal(viewName);
597 }), DispatcherPriority.Background);
598 }
599 }
600
625 private static void OnSelectViewChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
626 {
627 if (d is DreamineTabHost c)
628 {
629 c.ScheduleSwitch();
630 }
631 }
632
633 // =====================================================================
634 // Lifecycle
635 // =====================================================================
636
653 protected override void OnInitialized(EventArgs e)
654 {
655 base.OnInitialized(e);
656
657 // \brief Ensure initialization after XAML children (Items) are populated.
658 Dispatcher.InvokeAsync(() =>
659 {
660 TryInitViews();
661 }, DispatcherPriority.ContextIdle);
662 }
663
664 // =====================================================================
665 // Switching
666 // =====================================================================
667
676 private void ScheduleSwitch()
677 {
679 {
680 return;
681 }
682
683 _isSwitchScheduled = true;
684
685 Dispatcher.BeginInvoke(new Action(() =>
686 {
687 try
688 {
689 if (IsInDesignMode())
690 {
692 }
693 else
694 {
696 }
697 }
698 finally
699 {
700 _isSwitchScheduled = false;
701 }
702 }), DispatcherPriority.Input);
703 }
704
721 private void SwitchToViewInternal(string? targetKey)
722 {
723 if (_viewSwitcher == null)
724 {
725 return;
726 }
727
728 if (string.IsNullOrWhiteSpace(targetKey))
729 {
730 return;
731 }
732
733 bool isPopup = _viewSwitcher.IsPopupName(targetKey);
734
735 if (TargetAnalyzed)
736 {
737 IsCurrentTargetPopup = isPopup;
738 }
739
740 // \note IMPORTANT:
741 // - We intentionally call Switch(key) WITHOUT extra named parameters,
742 // because your ViewSwitcher signature currently does not accept targetAnalyzed (CS1739).
743 _viewSwitcher.Switch(targetKey, isPopup);
744
745 if (!isPopup && _views.TryGetValue(targetKey, out var nextView))
746 {
747 _currentView = nextView;
748 }
749 }
750
759 private void UpdateVisibleView()
760 {
761 if (_viewSwitcher == null)
762 {
763 return;
764 }
765
766 // \brief Prefer ordered keys (stable), not Dictionary iteration.
767 string? targetKey = _order.ElementAtOrDefault(SelectView);
768
769 // \brief If missing, fallback: if the original declared entry is "*_Popup", map it.
770 if (string.IsNullOrWhiteSpace(targetKey))
771 {
773 if (!string.IsNullOrWhiteSpace(raw) &&
774 raw.EndsWith("_Popup", StringComparison.OrdinalIgnoreCase))
775 {
776 string withoutSuffix = raw[..^6];
777 targetKey = DeriveSimpleKeyFromType(withoutSuffix);
778 }
779 }
780
781 if (string.IsNullOrWhiteSpace(targetKey))
782 {
783 return;
784 }
785
786 SwitchToViewInternal(targetKey);
787 }
788
798 {
799 if (_containerGrid == null || _views.Count == 0)
800 {
801 return;
802 }
803
804 int newIndex = SelectView;
805 if (newIndex < 0) newIndex = 0;
806 if (newIndex >= _order.Count) newIndex = _order.Count - 1;
807
808 if (newIndex == _designLastIndex && _containerGrid.Children.Count == 1)
809 {
810 return;
811 }
812
813 var newKey = _order.ElementAtOrDefault(newIndex);
814 if (string.IsNullOrWhiteSpace(newKey))
815 {
816 return;
817 }
818
819 var newView = _views[newKey];
820
821 _containerGrid.Children.Clear();
822 _containerGrid.Children.Add(newView);
823
824 _designLastIndex = newIndex;
825 }
826
827 // =====================================================================
828 // Visibility aware
829 // =====================================================================
830
863 private void OnRootIsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
864 {
865 if (sender is not FrameworkElement fe)
866 {
867 return;
868 }
869
870 if (fe.DataContext is not IVisibilityAware vm)
871 {
872 return;
873 }
874
875 bool isVisible = (bool)e.NewValue;
876
877 if (_lastVisibilityState.TryGetValue(fe, out bool last) && last == isVisible)
878 {
879 return;
880 }
881
882 _lastVisibilityState[fe] = isVisible;
883
884 if (isVisible)
885 {
886 vm.OnShown();
887 }
888 else
889 {
890 vm.OnHidden();
891 }
892 }
893
894 // =====================================================================
895 // Initialization
896 // =====================================================================
897
906 private void TryInitViews()
907 {
908 // \brief Prepare container
909 _containerGrid ??= new Grid();
910 Content = _containerGrid;
911
912 _containerGrid.Children.Clear();
913 _views.Clear();
914 _order.Clear();
915 _currentView = null;
916 _lastVisibilityState.Clear();
917
918 // \brief Build pairs from:
919 // 1) Items (XAML children) if present
920 // 2) otherwise DP collections (ContentList/ContentTypeList)
921 var pairs = BuildPairsFromItemsOrDps();
922
923 if (pairs.Count == 0)
924 {
925 return;
926 }
927
928 if (IsInDesignMode())
929 {
930 InitDesignViews(pairs);
932 return;
933 }
934
935 // \brief Runtime initialization
936 foreach (var (name, typeName) in pairs)
937 {
938 var result = ViewLoader.LoadViewWithViewModel(typeName, UseSingletonView);
939
940 if (result.IsPopup)
941 {
942 string actualTypeName = typeName.EndsWith("_Popup", StringComparison.OrdinalIgnoreCase)
943 ? typeName[..^6]
944 : typeName;
945
946 _popupManager.CreatePopup(actualTypeName, result);
947 continue;
948 }
949
950 if (result.View is null)
951 {
952 continue;
953 }
954
955 _views[name] = result.View;
956 _order.Add(name);
957
958 // \brief Visibility hook attach (dedupe)
959 result.View.IsVisibleChanged -= OnRootIsVisibleChanged;
960 result.View.IsVisibleChanged += OnRootIsVisibleChanged;
961
962 _containerGrid.Children.Add(result.View);
963
964 // \brief Default visibility
965 result.View.Visibility = UseSingletonView ? Visibility.Collapsed : Visibility.Visible;
966 }
967
969
970 // \brief Initial switch
971 if (!string.IsNullOrWhiteSpace(CurrentView) && _views.ContainsKey(CurrentView))
972 {
974 }
975 else
976 {
978 }
979 }
980
997 private List<(string name, string typeName)> BuildPairsFromItemsOrDps()
998 {
999 // \brief 1) Items (XAML children)
1000 var fromItems = BuildPairsFromItems();
1001 if (fromItems.Count > 0)
1002 {
1003 return EnsureUniqueNames(fromItems);
1004 }
1005
1006 // \brief 2) DPs (ContentList / ContentTypeList)
1008 return EnsureUniqueNames(fromDps);
1009 }
1010
1027 private List<(string name, string typeName)> BuildPairsFromItems()
1028 {
1029 var result = new List<(string name, string typeName)>();
1030
1031 if (Items == null || Items.Count == 0)
1032 {
1033 return result;
1034 }
1035
1036 foreach (var it in Items)
1037 {
1038 var raw = it?.Content?.ToString() ?? string.Empty;
1039 if (string.IsNullOrWhiteSpace(raw))
1040 {
1041 continue;
1042 }
1043
1044 // \brief If Popup flag is set, normalize to "*_Popup" convention.
1045 string typeName = it!.Popup && !raw.EndsWith("_Popup", StringComparison.OrdinalIgnoreCase)
1046 ? raw + "_Popup"
1047 : raw;
1048
1049 string name = !string.IsNullOrWhiteSpace(it.Key)
1050 ? it.Key
1051 : DeriveSimpleKeyFromType(typeName.EndsWith("_Popup", StringComparison.OrdinalIgnoreCase) ? typeName[..^6] : typeName);
1052
1053 // \brief If a separate Type is provided, use it as concrete type.
1054 if (!string.IsNullOrWhiteSpace(it.Type))
1055 {
1056 typeName = it.Type;
1057 if (it.Popup && !typeName.EndsWith("_Popup", StringComparison.OrdinalIgnoreCase))
1058 {
1059 typeName += "_Popup";
1060 }
1061 }
1062
1063 result.Add((name, typeName));
1064 }
1065
1066 return result;
1067 }
1068
1093 private string? GetDeclaredRawEntryAt(int index)
1094 {
1095 if (Items != null && Items.Count > 0)
1096 {
1097 var it = Items.ElementAtOrDefault(index);
1098 return it?.Content?.ToString();
1099 }
1100
1101 return ContentList?.ElementAtOrDefault(index);
1102 }
1103
1120 private void InitDesignViews(List<(string name, string typeName)> pairs)
1121 {
1122 foreach (var (name, typeName) in pairs)
1123 {
1125
1126 UserControl? view = null;
1127 foreach (var cand in candidates)
1128 {
1129 view = TryCreateDesignView(cand);
1130 if (view != null) break;
1131 }
1132
1133 view ??= MakeDesignPlaceholder(name);
1134
1135 if (AutoWireDesignViewModel && view.DataContext == null)
1136 {
1138 }
1139
1140 _views[name] = view;
1141 _order.Add(name);
1142 }
1143
1144 _containerGrid.Children.Clear();
1145
1146 var idx = Math.Clamp(SelectView, 0, Math.Max(0, _order.Count - 1));
1147 if (_order.Count > 0)
1148 {
1149 var key = _order[idx];
1150 _containerGrid.Children.Add(_views[key]);
1151 _designLastIndex = idx;
1152 }
1153 }
1154
1155 // =====================================================================
1156 // Helpers
1157 // =====================================================================
1158
1175 private bool IsInDesignMode()
1176 => DesignerProperties.GetIsInDesignMode(this);
1177
1210 private static List<(string name, string typeName)> EnsureUniqueNames(List<(string name, string typeName)> pairs)
1211 {
1212 var result = new List<(string name, string typeName)>(pairs);
1213 var seen = new HashSet<string>(StringComparer.Ordinal);
1214
1215 for (int i = 0; i < result.Count; i++)
1216 {
1217 var (n, t) = result[i];
1218 if (string.IsNullOrWhiteSpace(n))
1219 {
1221 }
1222
1223 if (seen.Add(n))
1224 {
1225 result[i] = (n, t);
1226 continue;
1227 }
1228
1229 int k = 2;
1230 string c;
1231 do
1232 {
1233 c = $"{n}_{k++}";
1234 }
1235 while (!seen.Add(c));
1236
1237 result[i] = (c, t);
1238 }
1239
1240 return result;
1241 }
1242
1275 private static List<(string name, string typeName)> BuildNameTypePairs_NoMutation(
1276 ObservableCollection<string>? names,
1277 ObservableCollection<string>? types)
1278 {
1279 var result = new List<(string name, string typeName)>();
1280
1281 var hasNames = names is { Count: > 0 };
1282 var hasTypes = types is { Count: > 0 };
1283
1284 if (!hasNames && !hasTypes)
1285 {
1286 return result;
1287 }
1288
1289 if (hasNames && hasTypes)
1290 {
1291 var count = Math.Min(names!.Count, types!.Count);
1292 for (int i = 0; i < count; i++)
1293 {
1294 var typeName = types[i] ?? string.Empty;
1295 var name = string.IsNullOrWhiteSpace(names[i])
1296 ? DeriveSimpleKeyFromType(typeName)
1297 : names[i];
1298
1299 result.Add((name, typeName));
1300 }
1301 }
1302 else if (hasTypes)
1303 {
1304 foreach (var t in types!)
1305 {
1306 var typeName = t ?? string.Empty;
1307 var name = DeriveSimpleKeyFromType(typeName);
1308 result.Add((name, typeName));
1309 }
1310 }
1311 else
1312 {
1313 foreach (var n in names!)
1314 {
1315 var typeName = n ?? string.Empty;
1316 var name = DeriveSimpleKeyFromType(typeName);
1317 result.Add((name, typeName));
1318 }
1319 }
1320
1321 return result;
1322 }
1323
1348 private static string DeriveSimpleKeyFromType(string raw)
1349 => string.IsNullOrWhiteSpace(raw)
1350 ? string.Empty
1351 : (raw.Contains('.') ? raw.Split('.').Last() : raw);
1352
1393 private static string[] BuildDesignTypeCandidates(string raw, string baseNs, string asmHint)
1394 {
1395 var list = new List<string> { raw };
1396
1397 if (!string.IsNullOrWhiteSpace(asmHint) && !raw.Contains(","))
1398 {
1399 list.Add($"{raw}, {asmHint}");
1400 }
1401
1402 if (!raw.Contains('.') && !string.IsNullOrWhiteSpace(baseNs))
1403 {
1404 var full = $"{baseNs}.{raw}";
1405 list.Add(full);
1406
1407 if (!string.IsNullOrWhiteSpace(asmHint))
1408 {
1409 list.Add($"{full}, {asmHint}");
1410 }
1411 }
1412
1413 return list.Distinct().ToArray();
1414 }
1415
1440 private static UserControl? TryCreateDesignView(string typeName)
1441 {
1442 try
1443 {
1444 Type? t = null;
1445
1446 if (typeName.Contains(","))
1447 {
1448 t = Type.GetType(typeName, throwOnError: false, ignoreCase: false);
1449 }
1450
1451 if (t == null)
1452 {
1453 t = FindTypeByName(typeName);
1454 }
1455
1456 if (t == null || !typeof(UserControl).IsAssignableFrom(t))
1457 {
1458 return null;
1459 }
1460
1461 try
1462 {
1463 return Activator.CreateInstance(t) as UserControl;
1464 }
1465 catch
1466 {
1467 return Activator.CreateInstance(t, nonPublic: true) as UserControl;
1468 }
1469 }
1470 catch
1471 {
1472 return null;
1473 }
1474 }
1475
1508 private static Type? FindTypeByName(string name)
1509 {
1510 var asms = AppDomain.CurrentDomain.GetAssemblies();
1511
1512 if (name.Contains('.'))
1513 {
1514 foreach (var asm in asms)
1515 {
1516 var t = asm.GetType(name, throwOnError: false, ignoreCase: false);
1517 if (t != null)
1518 {
1519 return t;
1520 }
1521 }
1522 }
1523
1524 foreach (var asm in asms)
1525 {
1526 try
1527 {
1528 var t = asm.GetTypes().FirstOrDefault(x => x.Name == name);
1529 if (t != null)
1530 {
1531 return t;
1532 }
1533 }
1534 catch
1535 {
1536 // ignore reflection errors
1537 }
1538 }
1539
1540 return null;
1541 }
1542
1567 private static UserControl MakeDesignPlaceholder(string title)
1568 {
1569 return new UserControl
1570 {
1571 Content = new Border
1572 {
1573 Background = System.Windows.Media.Brushes.White,
1574 BorderBrush = System.Windows.Media.Brushes.LightSteelBlue,
1575 BorderThickness = new Thickness(2),
1576 CornerRadius = new CornerRadius(6),
1577 Padding = new Thickness(8),
1578 Child = new TextBlock
1579 {
1580 Text = $"[design] {title}",
1581 FontSize = 16,
1582 Foreground = System.Windows.Media.Brushes.Black
1583 }
1584 }
1585 };
1586 }
1587
1612 private static void AttachDesignViewModelIfEmpty(UserControl view)
1613 {
1614 if (view.DataContext != null)
1615 {
1616 return;
1617 }
1618
1619 var vmType = ResolveDesignViewModelType(view.GetType());
1620 if (vmType == null)
1621 {
1622 return;
1623 }
1624
1625 try
1626 {
1627 var vm = DMContainer.Resolve(vmType);
1628 if (vm != null)
1629 {
1630 view.DataContext = vm;
1631 }
1632 }
1633 catch
1634 {
1635 // keep design resilient
1636 }
1637 }
1638
1671 private static Type? ResolveDesignViewModelType(Type viewType)
1672 {
1673 var fullCandidate = viewType.FullName + "ViewModel";
1674 var nsCandidate = $"{viewType.Namespace}.{viewType.Name}ViewModel";
1675 var shortCandidate = viewType.Name + "ViewModel";
1676
1677 var t = FindTypeByName(fullCandidate);
1678 if (t != null) return t;
1679
1680 t = FindTypeByName(nsCandidate);
1681 if (t != null) return t;
1682
1683 return FindTypeByName(shortCandidate);
1684 }
1685 }
1686
1702 public class DreamineTabHostItem : ContentControl
1703 {
1712 public static readonly DependencyProperty PopupProperty =
1713 DependencyProperty.Register(
1714 nameof(Popup),
1715 typeof(bool),
1716 typeof(DreamineTabHostItem),
1717 new PropertyMetadata(false));
1718
1727 public bool Popup
1728 {
1729 get => (bool)GetValue(PopupProperty);
1730 set => SetValue(PopupProperty, value);
1731 }
1732
1741 public static readonly DependencyProperty KeyProperty =
1742 DependencyProperty.Register(
1743 nameof(Key),
1744 typeof(string),
1745 typeof(DreamineTabHostItem),
1746 new PropertyMetadata(string.Empty));
1747
1756 public string Key
1757 {
1758 get => (string)GetValue(KeyProperty);
1759 set => SetValue(KeyProperty, value);
1760 }
1761
1770 public static readonly DependencyProperty TypeProperty =
1771 DependencyProperty.Register(
1772 nameof(Type),
1773 typeof(string),
1774 typeof(DreamineTabHostItem),
1775 new PropertyMetadata(string.Empty));
1776
1785 public string Type
1786 {
1787 get => (string)GetValue(TypeProperty);
1788 set => SetValue(TypeProperty, value);
1789 }
1790 }
1791}
static void OnContentInputsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
override void OnInitialized(EventArgs e)
List<(string name, string typeName)> BuildPairsFromItemsOrDps()
static readonly DependencyProperty DesignBaseNamespaceHintProperty
static readonly DependencyProperty SelectViewProperty
void InitDesignViews(List<(string name, string typeName)> pairs)
static string[] BuildDesignTypeCandidates(string raw, string baseNs, string asmHint)
static readonly DependencyProperty UseSingletonViewProperty
static List<(string name, string typeName)> EnsureUniqueNames(List<(string name, string typeName)> pairs)
static readonly DependencyPropertyKey IsCurrentTargetPopupPropertyKey
static ? UserControl TryCreateDesignView(string typeName)
static readonly DependencyProperty CurrentViewProperty
static string DeriveSimpleKeyFromType(string raw)
static readonly DependencyProperty AutoWireDesignViewModelProperty
static ? Type ResolveDesignViewModelType(Type viewType)
readonly Dictionary< FrameworkElement, bool > _lastVisibilityState
static UserControl MakeDesignPlaceholder(string title)
static readonly DependencyProperty IsCurrentTargetPopupProperty
static readonly DependencyProperty TargetAnalyzedProperty
List<(string name, string typeName)> BuildPairsFromItems()
static void OnSelectViewChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
ObservableCollection< DreamineTabHostItem > Items
static List<(string name, string typeName)> BuildNameTypePairs_NoMutation(ObservableCollection< string >? names, ObservableCollection< string >? types)
static void OnCurrentViewChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
static void OnDesignHintChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
ObservableCollection< string > ContentList
static readonly DependencyProperty ContentListProperty
readonly Dictionary< string, FrameworkElement > _views
void OnRootIsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
static readonly DependencyProperty DesignAssemblyHintProperty
static ? Type FindTypeByName(string name)
readonly PopupWindowManager _popupManager
static void AttachDesignViewModelIfEmpty(UserControl view)
ObservableCollection< string > ContentTypeList
static readonly DependencyProperty ContentTypeListProperty
static readonly DependencyProperty PopupProperty
static readonly DependencyProperty KeyProperty
static readonly DependencyProperty TypeProperty
static LoadedViewInfo LoadViewWithViewModel(string typeName, bool useSingletonView)