ItemsControlHelper.cs 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. using System.Windows.Controls;
  7. using System.Windows.Data;
  8. using System.Windows;
  9. using System.Windows.Controls.Primitives;
  10. namespace CyberX8_MainPages.Unity
  11. {
  12. public class ItemsControlHelper
  13. {
  14. /// <summary>
  15. /// 绑定 enum 类型所有值给 ItemsSource 赋值
  16. /// 必须绑定 SelectedItem
  17. /// </summary>
  18. public static readonly DependencyProperty EnumValuesToItemsSourceProperty = DependencyProperty.RegisterAttached(
  19. "EnumValuesToItemsSource", typeof(bool), typeof(ItemsControlHelper), new PropertyMetadata(default(bool), OnEnumValuesToItemsSourceChanged));
  20. public static void SetEnumValuesToItemsSource(DependencyObject element, bool value)
  21. {
  22. element.SetValue(EnumValuesToItemsSourceProperty, value);
  23. }
  24. public static bool GetEnumValuesToItemsSource(DependencyObject element)
  25. {
  26. return (bool)element.GetValue(EnumValuesToItemsSourceProperty);
  27. }
  28. private static void OnEnumValuesToItemsSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  29. {
  30. if (d is ItemsControl itemsControl && GetEnumValuesToItemsSource(itemsControl))
  31. {
  32. if (itemsControl.IsLoaded)
  33. {
  34. SetItemsSource(itemsControl);
  35. }
  36. else
  37. {
  38. itemsControl.Loaded += ItemsControl_Loaded;
  39. }
  40. }
  41. }
  42. private static void SetItemsSource(ItemsControl itemsControl)
  43. {
  44. var itemsBindingExpression = BindingOperations.GetBinding(itemsControl, ItemsControl.ItemsSourceProperty);
  45. if (itemsBindingExpression != null)
  46. {
  47. throw new InvalidOperationException("When using ItemsControlHelper.EnumValuesToItemsSource, cannot be used ItemsSource at the same time.");
  48. }
  49. if (itemsControl.Items.Count > 0)
  50. {
  51. throw new InvalidOperationException("When using ItemsControlHelper.EnumValuesToItemsSource, Items Collection must be null");
  52. }
  53. var bindingExpression = BindingOperations.GetBindingExpression(itemsControl, Selector.SelectedItemProperty);
  54. if (bindingExpression == null)
  55. {
  56. throw new InvalidOperationException("ItemsControl must be binding SelectedItem property");
  57. }
  58. var binding = bindingExpression.ParentBinding;
  59. var dataType = bindingExpression.DataItem?.GetType();
  60. var paths = binding.Path.Path.Split('.');
  61. foreach (var path in paths)
  62. {
  63. var propertyInfo = dataType?.GetProperty(path);
  64. if (propertyInfo == null)
  65. {
  66. return;
  67. }
  68. dataType = propertyInfo.PropertyType;
  69. }
  70. if (dataType != null && !dataType.IsEnum)
  71. {
  72. var underlyingType = Nullable.GetUnderlyingType(dataType);
  73. if (underlyingType == null)
  74. {
  75. return;
  76. }
  77. dataType = underlyingType;
  78. }
  79. var itemsSourceBinding = new Binding();
  80. itemsSourceBinding.Source = Enum.GetValues(dataType);
  81. itemsSourceBinding.Mode = BindingMode.OneWay;
  82. itemsControl.SetBinding(ItemsControl.ItemsSourceProperty, itemsSourceBinding);
  83. }
  84. private static void ItemsControl_Loaded(object sender, RoutedEventArgs e)
  85. {
  86. var itemsControl = (ItemsControl)sender;
  87. itemsControl.Loaded -= ItemsControl_Loaded;
  88. SetItemsSource(itemsControl);
  89. }
  90. }
  91. }