简体   繁体   English

如何在WPF(MVVM)中绑定数据网格列的宽度

[英]How to bind datagrid columns width in WPF (MVVM)

I am trying to bind a datagrid columns width but not working. 我正在尝试绑定一个数据网格列的宽度,但不起作用。

<DataGridTextColumn Binding="{Binding Name}" Width="{Binding GridNameWidth}" Header="Name" />

Here is the backend code: 这是后端代码:

public int GridNameWidth
{
    get
    {
        return 300;
    }
}

The backend code is never touched. 永远不会触碰到后端代码。 There are no errors but the name field has a default width. 没有错误,但name字段具有默认宽度。 I'd like to make width bind to my property. 我想使宽度绑定到我的财产。 I don't need two-way binding just need the width to be binded when the grid loads. 我不需要双向绑定,只需要在网格加载时绑定宽度即可。 Is this possible in wpf? 在wpf中这可能吗?

The DataGridTextColumn is an abstract object that isn't actually part of the VisualTree, so it doesn't make use of an inherited DataContext like you would expect with other controls. DataGridTextColumn是一个抽象对象,实际上不是VisualTree的一部分,因此它没有像其他控件那样使用继承的DataContext。

WPF knows how to parse something like the Binding property correctly and transfer the binding to each Cell, however something like Width simply gets evaluated as-is, and does not evaluate correctly because neither the DataContext nor VisualTree is there as expected. WPF知道如何正确解析诸如Binding属性之类的内容,并将Binding转移到每个Cell,但是诸如Width之类的内容只是按原样进行评估,并且由于DataContext和VisualTree都不存在,因此无法正确评估。

A common solution is to write your binding using a static data source instead. 常见的解决方案是改为使用静态数据源编写绑定。 Here's an example based on this answer , which uses x:Reference to refer to another control from the XAML markup : 这是基于此答案的示例, 示例使用x:Reference引用XAML标记中的另一个控件:

{Binding Source={x:Reference MyDataGrid}, Path=DataContext.NameColumnWidth}

Alternatively, you can define your own DataGridCellTemplate with a control that has it's Width bound to whatever the property is on your DataItem 另外,您可以定义一个自己的DataGridCellTemplate ,该控件的Width绑定到DataItem上的任何属性

As already mentioned the issue here is that DataGridTextColumn isn't in the logical or visual tree. 如前所述,这里的问题是DataGridTextColumn不在逻辑树或可视树中。 An alternative solution is this approach based on a binding proxy providing a binding. 一种替代解决方案是基于提供代理的绑定代理的此方法。 https://stackoverflow.com/a/46787502/5381620 https://stackoverflow.com/a/46787502/5381620

SourceCode 源代码

<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]}" Width="{Binding Data.Columns[0].Width, Source={StaticResource proxy}, Mode=TwoWay}" />
        <DataGridTextColumn Header="ProductId2" Binding="{Binding Path=Result[1]}" Width="{Binding Data.Columns[1].Width, Source={StaticResource proxy}, Mode=TwoWay}"/>
    </DataGrid.Columns>
</DataGrid>

class BindingProxy : Freezable
{
    //Override of Freezable
    protected override Freezable CreateInstanceCore()
    {
        return new BindingProxy();
    }
    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 DataGridLength Width
    {
        get { return m_width; }
        set { m_width = value; OnPropertyChanged("Width"); }
    }
    DataGridLength m_width;
}

For this implementation use a List<Column> or ObservableCollection directly in DataContext else adjust binding. 对于此实现,请直接在DataContext中使用List<Column>或ObservableCollection,否则请调整绑定。

如果您希望其工作,那么GridNameWidth的类型应为DataGridLength。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM