WPF 元素代理解决MVVM模式下DataGridColumn绑定无效问题

32 阅读1分钟

参考链接:www.cnblogs.com/Stay627/p/1…

在WPF中,DataGridTextColumn 不是可视树的一部分,因此它不会继承任何DataContext。这就是为什么你发现Thickness2Visibility值更新无效的原因。为了解决这个问题,你可以使用一个自定义的Freezable对象来捕获DataContext,并将其用于绑定。以下是具体的步骤和代码示例:

  1. 创建一个自定义的Freezable:这个类将用于存储和传递DataContext
public class BindingProxy : Freezable
{
    public static readonly DependencyProperty DataProperty =
        DependencyProperty.Register("Data", typeof(object), typeof(BindingProxy));

    public object Data
    {
        get { return (object)GetValue(DataProperty); }
        set { SetValue(DataProperty, value); }
    }

    protected override Freezable CreateInstanceCore()
    {
        return new BindingProxy();
    }
}
  1. 在XAML中定义这个Freezable对象作为资源,并将其Data属性绑定到你的Thickness2Visibility属性。
<Window.Resources>
    <local:BindingProxy x:Key="proxy" Data="{Binding Thickness2Visibility}" />
</Window.Resources>
  1. 修改你的DataGridTextColumnVisibility属性绑定,使用这个Freezable对象作为绑定源。
<DataGridTextColumn Header="Thickness2" Binding="{Binding Thickness2}" Width="Auto">
    <DataGridTextColumn.Visibility>
        <Binding Path="Data" Source="{StaticResource proxy}" Converter="{StaticResource ColumnVisibilityConverter}" />
    </DataGridTextColumn.Visibility>
</DataGridTextColumn>
  1. converter定义如下:
    //可从数据库取值,1为显示 0为隐藏
    [ValueConversion(typeof(int), typeof(Visibility))]
    public class ColumnVisibilityConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (null == value) return Visibility.Collapsed;
            Visibility visibility = Visibility.Visible;
            int visValue = (int)value;
            switch (visValue)
            {
                case 1:
                    visibility = Visibility.Visible;
                    break;
                default:
                    visibility = Visibility.Hidden;
                    break;
            }
            return visibility;
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return null;
        }
    }

这样,你的DataGridTextColumnVisibility属性就会根据Thickness2Visibility的值动态更新了。这种方法利用了Freezable对象可以跨线程共享并继承DataContext的特性,解决了DataGridTextColumn不在可视化树中的问题。