Dreamine.UI.Wpf.Controls 1.0.1
Dreamine.UI.Wpf.Controls 사용자 인터페이스 기능과 구성 요소를 제공합니다.
로딩중...
검색중...
일치하는것 없음
DreamineLabel.cs
이 파일의 문서화 페이지로 가기
1// \file DreamineLabel.cs
2// \brief Custom Label control used in VsLibrary.
3// \details
4// - Auto style merge (DreamineLabelStyle.xaml).
5// - Attached command execution via configurable triggers.
6// - Prevents duplicate handler attachment using internal hooked flag.
7
8using System;
9using System.Linq;
10using System.Windows;
11using System.Windows.Controls;
12using System.Windows.Input;
13using System.Windows.Media;
14
16{
25 public class DreamineLabel : Label
26 {
36 {
37 DefaultStyleKeyProperty.OverrideMetadata(typeof(DreamineLabel),
38 new FrameworkPropertyMetadata(typeof(DreamineLabel)));
39
40 var uri = new Uri("/Dreamine.UI.Wpf.Themes;component/DreamineLabelStyle.xaml", UriKind.RelativeOrAbsolute);
41
42 if (Application.Current != null)
43 {
44 bool alreadyAdded = Application.Current.Resources.MergedDictionaries
45 .OfType<ResourceDictionary>()
46 .Any(x => x.Source != null && x.Source.Equals(uri));
47
48 if (!alreadyAdded)
49 {
50 var dict = new ResourceDictionary { Source = uri };
51 Application.Current.Resources.MergedDictionaries.Add(dict);
52 }
53 }
54 }
55
56 // =====================================================================
57 // Attached Properties: Command / Parameter / Trigger
58 // =====================================================================
59
68 public static readonly DependencyProperty CommandProperty =
69 DependencyProperty.RegisterAttached(
70 "Command",
71 typeof(ICommand),
72 typeof(DreamineLabel),
73 new PropertyMetadata(null, OnCommandChanged));
74
83 public static readonly DependencyProperty CommandParameterProperty =
84 DependencyProperty.RegisterAttached(
85 "CommandParameter",
86 typeof(object),
87 typeof(DreamineLabel),
88 new PropertyMetadata(null));
89
98 public static readonly DependencyProperty CommandTriggerNameProperty =
99 DependencyProperty.RegisterAttached(
100 "CommandTriggerName",
101 typeof(string),
102 typeof(DreamineLabel),
103 new PropertyMetadata("PreviewMouseUp"));
104
113 private static readonly DependencyProperty IsHandlersHookedProperty =
114 DependencyProperty.RegisterAttached(
115 "IsHandlersHooked",
116 typeof(bool),
117 typeof(DreamineLabel),
118 new PropertyMetadata(false));
119
152 public static void SetCommandTriggerName(DependencyObject obj, string value)
153 => obj.SetValue(CommandTriggerNameProperty, value);
154
187 public static string GetCommandTriggerName(DependencyObject obj)
188 => obj.GetValue(CommandTriggerNameProperty) as string ?? string.Empty;
189
222 public static void SetCommand(DependencyObject obj, ICommand value)
223 => obj.SetValue(CommandProperty, value);
224
257 public static ICommand? GetCommand(DependencyObject obj)
258 => obj.GetValue(CommandProperty) as ICommand;
259
292 public static void SetCommandParameter(DependencyObject obj, object value)
293 => obj.SetValue(CommandParameterProperty, value);
294
327 public static object? GetCommandParameter(DependencyObject obj)
328 => obj.GetValue(CommandParameterProperty);
329
354 private static void OnCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
355 {
356 if (d is not UIElement element)
357 return;
358
359 // \brief Prevent duplicate hooking
360 bool hooked = (bool)(d.GetValue(IsHandlersHookedProperty) ?? false);
361 if (hooked)
362 return;
363
364 d.SetValue(IsHandlersHookedProperty, true);
365
366 // \brief Ensure hit-testable surface in common "label as button" usage
367 if (d is Control c && c.Background == null)
368 c.Background = Brushes.Transparent;
369
370 // \brief Mouse up
371 element.AddHandler(UIElement.PreviewMouseUpEvent,
372 new MouseButtonEventHandler((s, args) => TryExecuteCommand(d, "PreviewMouseUp", args)),
373 true);
374
375 // \brief Double click (Label does not have MouseDoubleClick by default; Control.MouseDoubleClickEvent is routed)
376 element.AddHandler(Control.MouseDoubleClickEvent,
377 new MouseButtonEventHandler((s, args) => TryExecuteCommand(d, "MouseDoubleClick", args)),
378 true);
379
380 // \brief Touch up
381 element.AddHandler(UIElement.TouchUpEvent,
382 new EventHandler<TouchEventArgs>((s, args) => TryExecuteCommand(d, "TouchUp", args)));
383 }
384
417 private static void TryExecuteCommand(DependencyObject d, string eventName, RoutedEventArgs eventArgs)
418 {
419 var rawTrigger = GetCommandTriggerName(d);
420 if (string.IsNullOrWhiteSpace(rawTrigger))
421 return;
422
423 var triggerList = rawTrigger.Split(',')
424 .Select(x => x.Trim())
425 .Where(x => !string.IsNullOrEmpty(x));
426
427 if (!triggerList.Contains(eventName, StringComparer.OrdinalIgnoreCase))
428 return;
429
430 var command = GetCommand(d);
431 var parameter = GetCommandParameter(d) ?? eventArgs;
432
433 if (command?.CanExecute(parameter) == true)
434 command.Execute(parameter);
435 }
436 }
437}
static void SetCommand(DependencyObject obj, ICommand value)
static readonly DependencyProperty CommandParameterProperty
static ? object GetCommandParameter(DependencyObject obj)
static readonly DependencyProperty CommandProperty
static string GetCommandTriggerName(DependencyObject obj)
static readonly DependencyProperty CommandTriggerNameProperty
static ? ICommand GetCommand(DependencyObject obj)
static void TryExecuteCommand(DependencyObject d, string eventName, RoutedEventArgs eventArgs)
static readonly DependencyProperty IsHandlersHookedProperty
static void OnCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
static void SetCommandParameter(DependencyObject obj, object value)
static void SetCommandTriggerName(DependencyObject obj, string value)