廢話不多說,客官先看圖
在WPF 中,控件禁用的時候,雖然可以利用觸發器去修改控件的本身的樣式,但是,鼠標樣式Cursor確不會生效。可是產品和UI怎麼會放過你呢,畢竟web控件可是可以改的。
解決方案:
利用裝飾器和附加屬性,完美繼承原先的樣式和邏輯,而且對所有控件都有效;
裝飾器代碼:
思路很簡單,就是給控件添加一個蒙層,禁用的時候,鼠標其實是位於在蒙層上;
public class UnableAdorner : Adorner
{
private readonly VisualCollection _collection;
private readonly Grid _grid;
private Border _border;
protected override int VisualChildrenCount => _collection.Count;
protected override Visual GetVisualChild(int index) => _collection[index];
public UnableAdorner(UIElement uIElement) : base(uIElement) {
_collection = new VisualCollection(this);
_grid = new Grid();
_border = new Border()
{
Background = Brushes.Transparent,
Cursor = (Cursor)TryFindResource("UnableCursor") ?? Cursors.No,
};
_grid.Children.Add(_border);
_collection.Add(_grid);
}
public void SetEnable(bool isEnable) {
_border.IsHitTestVisible = !isEnable;
}
protected override Size MeasureOverride(Size constraint)
{
return base.MeasureOverride(constraint);
}
protected override Size ArrangeOverride(Size finalSize)
{
_grid.Arrange(new Rect(finalSize));
return base.ArrangeOverride(finalSize);
}
}
附加屬性:
利用附加屬性,給控件添加對應的裝飾器
public class Assists
{
#region 控件IsEnable 屬性,用於重寫IsEnable樣式
public static bool GetIsEnable(DependencyObject obj)
{
return (bool)obj.GetValue(IsEnableProperty);
}
public static void SetIsEnable(DependencyObject obj, bool value)
{
obj.SetValue(IsEnableProperty, value);
}
// Using a DependencyProperty as the backing store for IsEnable. This enables animation, styling, binding, etc...
public static readonly DependencyProperty IsEnableProperty =
DependencyProperty.RegisterAttached("IsEnable", typeof(bool), typeof(Assists), new PropertyMetadata(true, IsEnablePropertyChanged));
private static void IsEnablePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is UIElement uIElement) {
var adorner = (UnableAdorner)uIElement.GetOrAddAdorner(typeof(UnableAdorner));
adorner.SetEnable((bool)e.NewValue);
}
}
#endregion
}
注意:裝飾器使用的時候 需要AdornerDecorator;