代码之家  ›  专栏  ›  技术社区  ›  RockWorld

WPF工具包数据列可见性绑定

  •  1
  • RockWorld  · 技术社区  · 15 年前

    我想用类的属性绑定DataGrid视图列可见性。 我正在将集合作为itemsource传递给网格。

    我不能这样做。知道为什么吗?

    2 回复  |  直到 14 年前
        1
  •  4
  •   Joseph Sturtevant    15 年前

    这个有点棘手。问题来自这样一个事实:datagrid.columns只是一个属性,而不是可视化树的一部分。这意味着像elementname或relativesource这样的常规绑定工具将无法工作。但是,如果重写DataGrid.DataContext属性的元数据,则可以使其正常工作。示例代码如下:

    <Window x:Class="DataGridColumnVisibilitySample.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:tk="clr-namespace:Microsoft.Windows.Controls;assembly=WPFToolkit"
        xmlns:l="clr-namespace:DataGridColumnVisibilitySample"
        Title="Window1" Height="300" Width="300">
        <Window.Resources>
            <l:VisibilityConverter x:Key="VisibilityC" />
        </Window.Resources>
        <DockPanel LastChildFill="True">
            <CheckBox DockPanel.Dock="Top" Margin="8" Content="Show Column B" IsChecked="{Binding ShowColumnB}" />
            <tk:DataGrid ItemsSource="{Binding Items}" AutoGenerateColumns="False" CanUserAddRows="False">
                <tk:DataGrid.Columns>
                    <tk:DataGridTextColumn Header="Column A" Binding="{Binding ColumnA}" />
                    <tk:DataGridTextColumn Header="Column B" Binding="{Binding ColumnB}"
                                           Visibility="{Binding (FrameworkElement.DataContext).ShowColumnB,
                                                                RelativeSource={x:Static RelativeSource.Self},
                                                                Converter={StaticResource VisibilityC}}" />
                    <tk:DataGridTextColumn Header="Column C" Binding="{Binding ColumnC}" />
                </tk:DataGrid.Columns>
            </tk:DataGrid>
        </DockPanel>
    </Window>
    

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Globalization;
    using System.Linq;
    using System.Windows;
    using System.Windows.Data;
    using Microsoft.Windows.Controls;
    
    namespace DataGridColumnVisibilitySample
    {
        public partial class Window1 : INotifyPropertyChanged
        {
            public Window1()
            {
                InitializeComponent();
                new DataGridContextHelper();  // Initialize Helper
                Items = Enumerable.Range(1, 3).Select(i => new MyItem {ColumnA = "A" + i, ColumnB = "B" + i, ColumnC = "C" + i}).ToList();
                DataContext = this;
            }
    
            public List<MyItem> Items { get; private set; }
    
            private bool mShowColumnB;
            public bool ShowColumnB
            {
                get { return mShowColumnB; }
                set
                {
                    if (mShowColumnB == value) return;
                    mShowColumnB = value;
                    if (PropertyChanged != null)
                        PropertyChanged(this, new PropertyChangedEventArgs("ShowColumnB"));
                }
            }
    
            public event PropertyChangedEventHandler PropertyChanged;
        }
    
        public class DataGridContextHelper
        {
            static DataGridContextHelper()
            {
                FrameworkElement.DataContextProperty.OverrideMetadata(typeof(DataGrid),
                    new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.Inherits, OnDataContextChanged));
            }
    
            public static void OnDataContextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
            {
                var grid = d as DataGrid;
                if (grid == null) return;
                foreach (var col in grid.Columns)
                    col.SetValue(FrameworkElement.DataContextProperty, e.NewValue);
            }
        }
    
        [ValueConversion(typeof(bool), typeof(Visibility))]
        public class VisibilityConverter : IValueConverter
        {
            public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
            {
                if (value is bool && (bool)value)
                    return Visibility.Visible;
                return Visibility.Collapsed;
            }
    
            public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
            {
                throw new NotImplementedException();
            }
        }
    
        public class MyItem
        {
            public string ColumnA { get; set; }
            public string ColumnB { get; set; }
            public string ColumnC { get; set; }
        }
    }
    

    我采购了 this post by Jaime Rodriguez 在创建我的解决方案时。

        2
  •  1
  •   steve    14 年前

    只要您的数据报在窗口、控件等中,它就工作,如果它在ControlTemplate中,这仍然不工作。