Datagridcolumn:通过BindingProxy绑定可见性和宽度显示不同的行为

时间:2017-10-17 09:53:51

标签: wpf mvvm data-binding datagrid visual-tree

由于数据网格的列不在datagrid的可视树中,我使用绑定代理的这种方法来绑定DataGridTextColumn的可见性。

https://www.thomaslevesque.com/2011/03/21/wpf-how-to-bind-to-data-when-the-datacontext-is-not-inherited/

由于某种原因,我想了解相同的方法对Visibility的工作正常,但对于列的Width属性却没有。 有人可以向我解释这种不同的行为吗?

代码示例

C#

class BindingProxy : Freezable
{
    #region Override of Freezable
    protected override Freezable CreateInstanceCore()
    {
        return new BindingProxy();
    }
    #endregion //Override of Freezable

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

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


public class Column : INotifyPropertyChanged
{

    public event PropertyChangedEventHandler PropertyChanged;
    protected internal void OnPropertyChanged(string propertyname)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyname));
    }

    public Column(bool visible = true)
    {
        if (visible == true)
            Visible = Visibility.Visible;
        else
            Visible = Visibility.Collapsed;

        Width = 200;
    }

    public Visibility Visible
    {
        get { return m_visible; }
        set { m_visible = value; OnPropertyChanged("Visible"); }
    }
    Visibility m_visible;

    public double Width
    {
        get { return m_width; }
        set { m_width = value; OnPropertyChanged("Width"); }
    }

    double m_width;
}

只是为了让它更容易重现

public partial class MainWindow : Window
{
    public MainWindow()
    {


        Lines = new ObservableCollection<tableline>();


        for (int i = 0; i< 5; i++)
            Lines.Add(new tableline());

        Columns = new List<Column>();
        Columns.Add(new Column(true));
        Columns.Add(new Column(false));

        InitializeComponent();
        DataContext = this;
    }

    public List<Column> Columns { get; set; }
    public ObservableCollection<tableline>Lines { get; set; }
}

public class tableline
{
    public tableline()
    {
        Result = new List<string>();
        int colCount = 2;
        for (int i = 0; i < colCount; i++)
        {
            Result.Add(i.ToString() + " some text");
        }

    }
    public List<string> Result { get; set; }
}

XAML

<DataGrid ItemsSource="{Binding Lines}" AutoGenerateColumns="False" >
    <DataGrid.Resources>
        <local:BindingProxy x:Key="proxy" Data="{Binding}"/>
    </DataGrid.Resources>
    <DataGrid.Columns>
        <DataGridTextColumn Header="ProductId1" Binding="{Binding Path=Result[0]}" Visibility="{Binding Data.Columns[0].Visible, Source={StaticResource proxy}}" Width="{Binding Data.Columns[0].Width, Source={StaticResource proxy}}" />
        <DataGridTextColumn Header="ProductId2" Binding="{Binding Path=Result[1]}" Visibility="{Binding Data.Columns[1].Visible, Source={StaticResource proxy}}" Width="{Binding Data.Columns[1].Width, Source={StaticResource proxy}}"/>
    </DataGrid.Columns>
</DataGrid>

只是为了让你知道我最初的目标是什么。我想为所有列设置一个自动宽度,但在绘制数据网格时使用“最大”列宽。但是,用户应该可以调整大小超过此限制。这就是为什么我不能使用MaxColumnWidth所以我认为最容易实现的方法是读取每列的宽度并将其设置为“最大”值(如果它大于限制)。

1 个答案:

答案 0 :(得分:1)

Width的{​​{1}}属性类型为DataGridColumn而非DataGridLength

更改源属性的类型:

double

public DataGridLength Width { get { return m_width; } set { m_width = value; OnPropertyChanged("Width"); } } DataGridLength m_width; 的{​​{1}}:

Mode