废话不多说,客官先看图
在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;