C# 如何在WPF(MVVM)中绑定datagrid列宽度

C# 如何在WPF(MVVM)中绑定datagrid列宽度,c#,wpf,c#-4.0,mvvm,C#,Wpf,C# 4.0,Mvvm,我正在尝试绑定datagrid列宽度,但不起作用 <DataGridTextColumn Binding="{Binding Name}" Width="{Binding GridNameWidth}" Header="Name" /> 后端代码永远不会被触及。没有错误,但名称字段具有默认宽度。我想把宽度绑定到我的财产上。我不需要双向绑定,只需要在网格加载时绑定宽度。这在wpf中可能吗?如果您想让它工作,GridNameWidth应该是DataGridLength类型。如果您想让它

我正在尝试绑定datagrid列宽度,但不起作用

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

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

如果您想让它工作,GridNameWidth应该是DataGridLength类型。

如果您想让它工作,GridNameWidth应该是DataGridLength类型。

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

WPF知道如何正确解析
Binding
属性之类的内容,并将绑定传输到每个单元格,但是像Width这样的内容只是按原样计算,不能正确计算,因为DataContext和VisualTree都没有按预期的那样存在

一种常见的解决方案是使用静态数据源编写绑定。下面是一个基于的示例,用于引用XAML标记中的另一个控件:

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

或者,您可以使用一个控件定义自己的
DataGridCellTemplate
,该控件的宽度绑定到DataItem上的任何属性

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

WPF知道如何正确解析
Binding
属性之类的内容,并将绑定传输到每个单元格,但是像Width这样的内容只是按原样计算,不能正确计算,因为DataContext和VisualTree都没有按预期的那样存在

一种常见的解决方案是使用静态数据源编写绑定。下面是一个基于的示例,用于引用XAML标记中的另一个控件:

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

或者,您可以使用一个控件定义自己的
DataGridCellTemplate
,该控件的宽度绑定到DataItem上的任何属性,正如前面提到的,这里的问题是DataGridTextColumn不在逻辑树或可视树中。 另一种解决方案是基于提供绑定的绑定代理的这种方法。

源代码

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

对于此实现,请直接在DataContext中使用
列表
或ObservableCollection,否则请调整绑定。

如前所述,这里的问题是DataGridTextColumn不在逻辑树或可视树中。 另一种解决方案是基于提供绑定的绑定代理的这种方法。

源代码

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


对于此实现,请直接在DataContext中使用
列表
或ObservableCollection,否则请调整绑定。

有一个为double类型定义的隐式转换器。看,有没有一种方法可以让它使用MVVM工作?如果不是的话,我怎么用你的方式做呢?你可以用双人床。或者为int实现一个值转换器。GridNameWidth属性在哪里?在代码隐藏或ViewModel?System.Windows.Data中,错误:2:找不到目标元素的治理FrameworkElement或FrameworkContentElement。BindingExpression:Path=GridNameWidth;DataItem=null;目标元素是“DataGridTextColumn”(HashCode=738321);目标属性为“Width”(类型为“DataGridLength”)存在为类型double定义的隐式转换器。看,有没有一种方法可以让它使用MVVM工作?如果不是的话,我怎么用你的方式做呢?你可以用双人床。或者为int实现一个值转换器。GridNameWidth属性在哪里?在代码隐藏或ViewModel?System.Windows.Data中,错误:2:找不到目标元素的治理FrameworkElement或FrameworkContentElement。BindingExpression:Path=GridNameWidth;DataItem=null;目标元素是“DataGridTextColumn”(HashCode=738321);目标属性为“宽度”(类型为“DataGridLength”),您的数据结构是什么样的?包含
Name
属性的同一对象是否也包含
GridNameWidth
属性?正确,同一对象包含my Name对象。通过模型属性设置视觉效果的宽度不是mvvm。您的数据结构是什么样的?包含
Name
属性的同一对象是否也包含
GridNameWidth
属性?正确,同一对象包含my Name对象。通过模型属性设置视觉效果的宽度不是mvvm。这可能是正确的,但我仍然不明白。你是说我不应该使用我的'GridNameWidth'属性,而是应该在窗口上使用另一个控件?我读了另一个答案,但他没有给出一个明确的例子。@Luke101问题是在生成UI时DataGridTextColumn实际上并不存在,因此绑定的计算结果不正确。作为替代方案,我们可以将绑定设置为在生成单元格时存在的静态内容。
Source={x:Reference…}
的意思是“在XAML中找到名为XXX的对象,并将其用作此绑定的源”,因此,理论上,我们可以将其与
Path=DataContext.NameColumnWidth
结合使用,告诉它使用
MyDataGrid.DataContext.NameColumnWidth
中的值,这可能是正确的,但我仍然不明白。你是说我不应该使用我的'GridNameWidth'属性,而是应该在窗口上使用另一个控件?我读了另一个答案,但他没有给出一个明确的例子。@Luke101问题是在生成UI时DataGridTextColumn实际上并不存在,因此绑定的计算结果不正确。作为替代方案,我们可以将绑定设置为在生成单元格时存在的静态内容。
Source={x:Reference…}
的意思是“在XAML中找到名为XXX的对象,并将其用作此绑定的源”,理论上如此