繁体   English   中英

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

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

我正在尝试绑定一个数据网格列的宽度,但不起作用。

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

这是后端代码:

public int GridNameWidth
{
    get
    {
        return 300;
    }
}

永远不会触碰到后端代码。 没有错误,但name字段具有默认宽度。 我想使宽度绑定到我的财产。 我不需要双向绑定,只需要在网格加载时绑定宽度即可。 在wpf中这可能吗?

DataGridTextColumn是一个抽象对象,实际上不是VisualTree的一部分,因此它没有像其他控件那样使用继承的DataContext。

WPF知道如何正确解析诸如Binding属性之类的内容,并将Binding转移到每个Cell,但是诸如Width之类的内容只是按原样进行评估,并且由于DataContext和VisualTree都不存在,因此无法正确评估。

常见的解决方案是改为使用静态数据源编写绑定。 这是基于此答案的示例, 示例使用x:Reference引用XAML标记中的另一个控件:

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

另外,您可以定义一个自己的DataGridCellTemplate ,该控件的Width绑定到DataItem上的任何属性

如前所述,这里的问题是DataGridTextColumn不在逻辑树或可视树中。 一种替代解决方案是基于提供代理的绑定代理的此方法。 https://stackoverflow.com/a/46787502/5381620

源代码

<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;
}

对于此实现,请直接在DataContext中使用List<Column>或ObservableCollection,否则请调整绑定。

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

暂无
暂无

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

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