zoukankan      html  css  js  c++  java
  • 由DataGridTextColumn不能获取到父级DataContext引发的思考

      在项目中使用DataGrid需要根据业务动态隐藏某些列,思路都是给DataGrid中列的Visibility属性绑定值来实现(项目使用MVVM),如下

    <DataGridTextColumn Header="Name" Binding="{Binding Name}" Visibility="{Binding RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type DataGrid}},Path=DataContext.IsVisible,Converter={StaticResource BooleanToVisibilityConverter}}"></DataGridTextColumn>


    如果不是在DataGridTextColumn上绑定,那么这段代码是可以工作的,问题出在DataGridTextColumn上,我们来看它的继承层次

    它不是FrameworkElement的派生类,所以它不具有DataContext属性,也就是说,即使DataGrid有DataContext,DataGridTextColumn也不能得到它,Visibility找不到DataContext自然绑定不上,这就是为什么上面的绑定失效的原因,同样其他类型的列也有同样的问题。那么如何优雅地解决问题呢?国际友人给出了这样一个方法,既然DataGridTextColumn不能从父级那里得到DataContext,那么直接给她的Visibility指定一个DataContext,实现如下

    • 首先创建一个可以承载DataContext的绑定代理类BindingProxy
    • 然后将这个BindingProxy当作资源,获得DataContext
    • 将DataGridTextColumn的Visibility的DataContext指定为这个BindingProxy

    BindingProxy.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    
    namespace WPF_DataContext_Sample
    {
        public class BindingProxy:Freezable
        {
            protected override Freezable CreateInstanceCore()
            {
                return new BindingProxy();
                
            }
    
            public object DataContext
            {
                get
                {
                    return (object)GetValue(DataContextProperty);
                }
                set
                {
                    SetValue(DataContextProperty, value);
                }
            }
    
            // Using a DependencyProperty as the backing store for DataContext.  This enables animation, styling, binding, etc...
            public static readonly DependencyProperty DataContextProperty =
                DependencyProperty.Register("DataContext", typeof(object), typeof(BindingProxy), new PropertyMetadata(null));
        }
    }

    MainWindow.xaml

    <Window x:Class="WPF_DataContext_Sample.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:wpfDataContextSample="clr-namespace:WPF_DataContext_Sample"
            Title="MainWindow" Height="350" Width="525">
        <Window.Resources>
            <wpfDataContextSample:Converter x:Key="Converter"></wpfDataContextSample:Converter>
            
            <wpfDataContextSample:BindingProxy x:Key="BindingProxy" DataContext="{Binding}"></wpfDataContextSample:BindingProxy>
        </Window.Resources>
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition/>
                <RowDefinition Height="0.1*"/>
            </Grid.RowDefinitions>
            <DataGrid AutoGenerateColumns="False" ItemsSource="{Binding Students}">
                <DataGrid.Columns>
    
                    <DataGridTextColumn Header="Id" Binding="{Binding Id}"></DataGridTextColumn>
    
                    <!--这样的绑定会失败-->
                    <!--<DataGridTextColumn Header="Name" Binding="{Binding Name}" Visibility="{Binding RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type DataGrid}},Path=DataContext.IsShow,Converter={StaticResource BooleanToVisibilityConverter}}"></DataGridTextColumn>-->
    
                    <DataGridTextColumn Header="Name" Binding="{Binding Name}" Visibility="{Binding DataContext.IsShow,Source={StaticResource BindingProxy},Converter={StaticResource Converter}}"></DataGridTextColumn>
                    
                    <DataGridTextColumn Header="Sex" Binding="{Binding Sex}"></DataGridTextColumn>
    
                </DataGrid.Columns>
            </DataGrid>
            
            <StackPanel Orientation="Horizontal" Grid.Row="1">
                <Button Width="100" Height="30" Content="隐藏Name" Click="ButtonBase_OnClick"></Button>
            </StackPanel>
        </Grid>
    </Window>

    这样就能优雅地解决了这个问题

    原文地址http://www.thomaslevesque.com/2011/03/21/wpf-how-to-bind-to-data-when-the-datacontext-is-not-inherited/

    Demo:WPF_DataContextAndDataGridTextColumn_Sample.rar

  • 相关阅读:
    调研《构建之法》指导下的历届作品
    需求分析与原型设计
    软件工程的实践项目课程的自我目标
    php 字符串的一些操作,以便记忆
    MOTT的学习(一)
    session,cookie
    php Curl_setop 的学习
    使用Git进行代码管理的心得
    搭建andiord sdk和安装eclipse adt插件的个人小体会
    这些天自身努力的体会,关于java方面的
  • 原文地址:https://www.cnblogs.com/action98/p/3535934.html
Copyright © 2011-2022 走看看