WPF DataGrid Visibility的綁定


  場景:根據配置文件顯示DataGrid中的某些列。

  問題:Columns集合只是DataGrid的一個屬性,這個集合在邏輯樹或視覺樹中是看不到的,也不會繼承DataContext屬性。

  通過網上查閱各種資料,方法可以歸結以下幾種,下面將一一展示。

  方法一:對DataGridColumn附加DataContext屬性

  該方法需要用到一個幫助類(需要創建一個全局實例),具體內容如下:

public class DataGridContextHelper
    {
        static DataGridContextHelper()
        {

            DependencyProperty dp = FrameworkElement.DataContextProperty.AddOwner(typeof(DataGridColumn));
            FrameworkElement.DataContextProperty.OverrideMetadata(typeof(DataGrid),
            new FrameworkPropertyMetadata
               (null, FrameworkPropertyMetadataOptions.Inherits,
               new PropertyChangedCallback(OnDataContextChanged)));

        }

        public static void OnDataContextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGrid grid = d as DataGrid;
            if (grid != null)
            {
                foreach (DataGridColumn col in grid.Columns)
                {
                    col.SetValue(FrameworkElement.DataContextProperty, e.NewValue);
                }
            }
        }
    } 

  前台綁定示例

<DataGridTextColumn x:Name="col2" Header="TestColumn"
                                    Visibility="{Binding (FrameworkElement.DataContext).Show,RelativeSource={RelativeSource Self},Converter={StaticResource cc}}"></DataGridTextColumn>

 

  后台綁定示例

var binding = new Binding();
            binding.Mode = BindingMode.OneWay;
            binding.RelativeSource=new RelativeSource(RelativeSourceMode.Self);
            binding.Converter = new BooleanToVisibilityConverter();
            binding.Path=new PropertyPath("(FrameworkElement.DataContext).Show");
            BindingOperations.SetBinding(obj, DataGridColumn.VisibilityProperty, binding);

  方法二:通過Source直接與Vm綁定

  示例代碼:

var binding = new Binding();
            binding.Mode = BindingMode.OneWay;
            binding.Source = vm;
            binding.Converter = new BooleanToVisibilityConverter();
            binding.Path = new PropertyPath("Show");
            BindingOperations.SetBinding(obj, DataGridColumn.VisibilityProperty, binding);

 

  方法三:通過Source與VM的一個代理類進行綁定

  代理類

  Freezable可以繼承DataContext即使它們不在視覺樹或邏輯樹中

public class BindingProxy : Freezable
    {
        #region Overrides of Freezable

        protected override Freezable CreateInstanceCore()
        {
            return new BindingProxy();
        }

        #endregion

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

        public static readonly DependencyProperty DataProperty =
            DependencyProperty.Register("Data", typeof(object),
                                         typeof(BindingProxy));
    }

  前台綁定代碼

 <DataGrid x:Name="dg" HorizontalAlignment="Left" VerticalAlignment="Top" Height="253" Width="436" ItemsSource="{Binding Persons}"
                  AutoGenerateColumns="False">
            <DataGrid.Resources>
                <dgTest:BindingProxy x:Key="proxy" Data="{Binding}"/>
            </DataGrid.Resources>
            <DataGrid.Columns>
                <DataGridTextColumn x:Name="col1" Header="TestColumn" Binding="{Binding Name}"></DataGridTextColumn>
                <DataGridTextColumn x:Name="col2" Header="TestColumn"
                                    Visibility="{Binding (FrameworkElement.DataContext).Show,RelativeSource={RelativeSource Self},Converter={StaticResource cc}}"></DataGridTextColumn>
                <DataGridTextColumn x:Name="col3" Header="TestColumn" Visibility="{Binding Data.Show,Source={StaticResource proxy},Converter={StaticResource cc}}"></DataGridTextColumn>
            </DataGrid.Columns>
        </DataGrid>

 

  方法四:通過一個代理控件來實現

  代理控件與代理對象的解決方式類似,都是因為其可以繼承DataContext屬性,只是一個在邏輯樹中看的到,一個看不到。示例如下:

<FrameworkElement x:Name="dummyElement" Visibility="Collapsed"/>
    <DataGrid>
        <DataGrid.Columns>
            <DataGridTextColumn Header="Test"
                                Binding="{Binding Name}"
                                Visibility="{Binding DataContext.IsEnable,
                                          Source={x:Reference dummyElement}}"/>
        </DataGrid.Columns>
    </DataGrid>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM