【问题标题】:WPF DataGrid - Binding Source and Width to different objectsWPF DataGrid - 将源和宽度绑定到不同的对象
【发布时间】:2014-03-24 14:46:15
【问题描述】:

在我的 WPF 应用程序中,我有一个绑定到视图模型中的集合的 DataGrid,但我希望第一列的宽度等于视图模型本身的属性,如下所示:

public ObservableCollection<Booking> Bookings
{
    return repository.Bookings();
}

public int MaxWidth
{
    return 100;
}

(我意识到像这样绑定到固定属性没有意义 - 这是为了演示目的)

<UserControl>
    <DataGrid DataContext="{Binding Bookings}">
        <DataGrid.Columns>
            <DataGridTextColumn Width="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.MaxWidth}" Header="Provider" Binding="{Binding Name}" />
        </DataGrid.Columns>
    </DataGrid>
</UserControl>

但如果我这样做,列的宽度将保持在默认值 - 即宽度足以容纳其值。

我做错了什么?

编辑:尝试了这个,看看发生了什么:

<Label Name="tricky" Content="500" Visibility="Collapsed"></Label>
...
<DataGridTextColumn Width="{Binding ElementName=tricky, Path=Content}" Header="Provider" Binding="{Binding Name}" />

什么都没做。不可以动态设置宽度吗?

【问题讨论】:

  • 你的RelativeSource绑定不应该找到DataGrid而不是UserControl吗?
  • 我不这么认为 - 我正在寻找的属性属于整个父 ViewModel,而不是 DataGrid。快速测试确认它没有任何区别。
  • @MattThrower 是正确的。您需要 UserControl 的 DataContext 范围,而不是 Booking 对象。 DataGrid 绑定何时发生?
  • 嗯。这是基于 MVVM 的,所以我不控制绑定的时间。 Bookings 在 MaxWidth 之前填充,如果这就是您的意思的话。
  • 我认为问题在于DataGridTextColum 不是可视树的一部分(可以使用Snoop 进行验证),因此绑定永远不会得到解决。从DataGridTextColumn 获取的数据用于构建DataGridCell 模板,在构建模板时,未设置DataContext。我的建议是使用DataGridTemplateColumn,并指定您自己的具有所需宽度绑定的 CellTemplate。

标签: c# wpf mvvm datagrid


【解决方案1】:

我认为问题在于DataGridTextColum 不是可视树的一部分(可以使用Snoop 进行验证),因此绑定永远不会得到解决。

DataGridTextColumn 获取的数据用于构建DataGridCell 模板,在构建模板时,DataContext 未设置。

我的建议是使用DataGridTemplateColumn,并指定您自己的CellTemplate,它具有您需要的Width 绑定。

【讨论】:

    【解决方案2】:

    我使用的另外一个有用的功能如下

    IsEnabled="{Binding DataContext.IsEnabled,RelativeSource={RelativeSource AncestorType={x:Type Window}}}"  />
    

    这允许您链接到网格的 itemssource 之外的属性。

    【讨论】:

      【解决方案3】:

      MaxWidthBookings 不是兄弟姐妹吗?所以它们的绑定表达式应该是相同的。

      查看您的第一个 XAML:Path=DataContext.MaxWidth - 删除 DataContext
      看第二个XAML:不需要指定Path两次,第一个Path就够了,我什至不确定实际构造是否有效。

      通常,许多低级 UI 属性是 POCO 而不是 DP,只要确保您的目标是 DP。

      更新 - 您可能想要做的是使用 FallbackValue = 900 作为绑定表达式的一部分,只是为了缩小问题范围 - 无论是绑定问题还是目标属性不是适合用作绑定目标。

      更新 2 - 大多数情况下,您会发现自己在进行低级别的 UI 管理时很快就会失去动力,创建 MVColum、管理标题、宽度等通常是有益的创建一个行为,它可以一次性应用所有这些设置。同样,您将不会依赖于目标属性的风格,因为您将在代码中直接设置它们。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-10-17
        • 1970-01-01
        • 2015-04-27
        • 2012-03-15
        • 2015-03-27
        • 2012-11-16
        • 2017-08-07
        • 1970-01-01
        相关资源
        最近更新 更多