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

时间:2010-04-26 13:26:35

标签: c# wpf wpftoolkit

我想将datagridview列可见性与class的属性绑定。 我将一个集合作为DataSource传递给网格。

我无法做到这一点。知道为什么吗?

2 个答案:

答案 0 :(得分:4)

这个有点棘手。问题来自于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

答案 1 :(得分:1)

只要你的数据网格在一个窗口,控件等中,如果它在一个控件模板中,这仍然无法正常工作