WPF DataGrid - 将列与页面的ViewModel进行数据绑定

5

我正在尝试将一个列的数据绑定到页面ViewModel中的数据(而不是网格绑定的对象)。

下面的代码在这里被推荐使用,但没有成功。

   <DataGridTemplateColumn>
      <DataGridTemplateColumn.CellTemplate>
         <DataTemplate>
            <Button Content="{Binding ElementName=LayoutRoot, Path=DataContext.JUNK}"></Button>
         </DataTemplate>
      </DataGridTemplateColumn.CellTemplate>
   </DataGridTemplateColumn>

在我的 ViewModel 中

public string JUNK { get; set; }

在ViewModel的构造函数中将其设置为"HELLO"

有人看出我做错了什么吗?

编辑

这是整个XAML。相关列在网格内的网格最下方

另外 - 我无法再次将整个源代码放入这里(不确定是Citrix还是其他原因),但我将那个在数据网格按钮中不起作用的完全相同的绑定表达式放到了一个普通的TextBlock的文本中,它像魔术一样奏效了。我还向网格添加了一个新的虚拟文本列,并将该绑定表达式用于文本,但它仍然起作用。它似乎是正确的绑定表达式,但是拒绝在网格附近工作。

<UserControl x:Class="MainApp.WPF.ucFmvHistoryDisplayGrid"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="1000" x:Name="LayoutRoot">

<UserControl.Resources>
    <Style x:Name="rightAlignedColumn" x:Key="rightAlignedColumn" TargetType="TextBlock">
        <Setter Property="HorizontalAlignment" Value="Right" />
    </Style>

    <Style x:Name="centerAlignedColumn" x:Key="centerAlignedColumn" TargetType="TextBlock">
        <Setter Property="HorizontalAlignment" Value="Center" />
    </Style>
</UserControl.Resources>

<Grid>
    <DataGrid x:Name="dbTop" ItemsSource="{Binding PropertyGroupSource}" HorizontalAlignment="Left" Background="White" CanUserAddRows="False" CanUserDeleteRows="False" CanUserReorderColumns="False" CanUserResizeRows="False" IsReadOnly="True" AutoGenerateColumns="False" Grid.Row="1" Width="800">
        <DataGrid.Columns>
            <DataGridTextColumn Width="120" Header="Property Num" Binding="{Binding PropertyNum}"></DataGridTextColumn>
            <DataGridTextColumn Width="120" Header="Alt Description" Binding="{Binding AltDescription}"></DataGridTextColumn>
            <DataGridTextColumn Width="80" Header="County" Binding="{Binding County}"></DataGridTextColumn>
            <DataGridTextColumn Width="100" Header="State" Binding="{Binding State}" ElementStyle="{StaticResource centerAlignedColumn}"></DataGridTextColumn>
            <DataGridTextColumn Width="85" Header="Phase" Binding="{Binding Phase}"></DataGridTextColumn>
            <DataGridTextColumn Width="85" Header="FMV" Binding="{Binding FmvTotal}"></DataGridTextColumn>
            <DataGridTextColumn Width="100" Header="Assessed Value" Binding="{Binding AssessedValueTotal}"></DataGridTextColumn>
        </DataGrid.Columns>
        <DataGrid.RowDetailsTemplate>
            <DataTemplate>
                <Border Margin="5" BorderBrush="Black" BorderThickness="1">
                    <DataGrid Margin="5" Background="White" CanUserAddRows="False" CanUserDeleteRows="False" CanUserReorderColumns="False" CanUserResizeRows="False" IsReadOnly="True" AutoGenerateColumns="False" Grid.Row="1" ItemsSource="{Binding PropertyFmvSource}">
                        <DataGrid.Columns>
                            <DataGridTextColumn Width="125" Header="County Acct Num" Binding="{Binding Property.CountyAccountNum, StringFormat=d}" ElementStyle="{StaticResource rightAlignedColumn}"></DataGridTextColumn>
                            <DataGridTextColumn Width="80" Header="City" Binding="{Binding Property.City, StringFormat=d}" ElementStyle="{StaticResource rightAlignedColumn}"></DataGridTextColumn>
                            <DataGridTextColumn Width="80" Header="Jurisdiction" Binding="{Binding Property.Jurisdiction, StringFormat=d}" ElementStyle="{StaticResource rightAlignedColumn}"></DataGridTextColumn>
                            <DataGridTextColumn Width="80" Header="FMV Date" Binding="{Binding MostRecentFMV.FMVDate, StringFormat=d}" ElementStyle="{StaticResource rightAlignedColumn}"></DataGridTextColumn>
                            <DataGridTextColumn Width="100" Header="FMV" Binding="{Binding MostRecentFMV.FMV, StringFormat=N0}" ElementStyle="{StaticResource rightAlignedColumn}"></DataGridTextColumn>
                            <DataGridTextColumn Width="85" Header="Assess Ratio" Binding="{Binding MostRecentFMV.AssessmentRatio, StringFormat=N3}" ElementStyle="{StaticResource rightAlignedColumn}"></DataGridTextColumn>
                            <DataGridTextColumn Width="105" Header="Assessed Value" Binding="{Binding MostRecentFMV.AssessedValue, StringFormat=N0}" ElementStyle="{StaticResource rightAlignedColumn}"></DataGridTextColumn>
                            <DataGridTemplateColumn>
                                <DataGridTemplateColumn.CellTemplate>
                                    <DataTemplate>
                                        <Button Content="{Binding ElementName=LayoutRoot, Path=DataContext.JUNK}"></Button>
                                    </DataTemplate>
                                </DataGridTemplateColumn.CellTemplate>
                            </DataGridTemplateColumn>
                        </DataGrid.Columns>
                    </DataGrid>
                </Border>
            </DataTemplate>
        </DataGrid.RowDetailsTemplate>
    </DataGrid>
</Grid>


你是否有一个名为“LayoutRoot”的元素,并将其数据上下文设置为你的视图模型(ViewModel)?能否发布更多XAML(特别是"LayoutRoot"元素的定义)?谢谢! - Mark Carpenter
我并不是WPF专家,但LayoutRoot不是内置的吗 - 它自动成为范围内最顶层的UI元素,对吗?还是说完全错误,我需要将LayoutRoot的名称添加到该UI元素中?实际上,我可以很清楚地看到这就是情况。只需在答案中写下来,我就会关闭它。谢谢。 - Adam Rackis
实际上,它没有。我原本以为它会有的。现在正在更新问题... - Adam Rackis
+1,非常好的问题。我对这种行为感到非常惊讶,我发布的答案并不是一个很好的解决方案,但这是我能想到的唯一解决方案。我不知道为什么它不能使用ElementName或RelativeSource,但我会关注这个问题,看看是否有人提出更好的解释或解决方法 :) - Fredrik Hedblad
@Adam Rackis:请看我的更新答案,里面有个解决方法。 - Fredrik Hedblad
2个回答

3

使用RelativeSource绑定到包含DataGrid的DataContext应该可以工作:

<Button Content="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid, AncestorLevel=2}, Path=DataContext.JUNK}"></Button>

由于您已经嵌套了DataGrids,所以祖先级别必须设置为“2”,以绑定到最外层DataGrid的DataContext。

哇,原来如此简单。谢谢! - Adam Rackis
哇,这真的帮助我使用视图模型绑定样式化了一个DataGrid列 +1。 - markp3rry

2

更新

@Danny Shisler的答案是正确的。保留此答案,因为它展示了如何在DataGridColumn内部进行绑定,该列不在可视树中并且没有DataContext。


这里有一篇博客文章介绍了解决此问题的方法:http://blogs.infragistics.com/blogs/josh_smith/archive/2008/06/26/data-binding-the-isvisible-property-of-contextualtabgroup.aspx

解决方法是创建一个DataContextSpy,看起来像这样:

DataContextSpy

public class DataContextSpy
: Freezable // Enable ElementName and DataContext bindings
{
    public DataContextSpy()
    {
        // This binding allows the spy to inherit a DataContext.
        BindingOperations.SetBinding(this, DataContextProperty, new Binding());
    }

    public object DataContext
    {
        get { return (object)GetValue(DataContextProperty); }
        set { SetValue(DataContextProperty, value); }
    }

    // Borrow the DataContext dependency property from FrameworkElement.
    public static readonly DependencyProperty DataContextProperty =
        FrameworkElement.DataContextProperty.AddOwner(typeof(DataContextSpy));

    protected override Freezable CreateInstanceCore()
    {
        // We are required to override this abstract method.
        throw new NotImplementedException();
    }
}

然后您可以使用DataContextSpy的实例作为DataGridColumn中绑定的源,如下所示:

<Grid Name="LayoutRoot">
    <Grid.Resources>
        <local:DataContextSpy x:Key="dataContextSpy" />
    </Grid.Resources>
    <DataGrid ...>
        <DataGrid.Columns>
            <DataGridTemplateColumn Header="{Binding Path=DataContext.JUNK,
                                           Source={StaticResource dataContextSpy}}">
                <!--..-->
            </DataGridTemplateColumn>
            <!--..-->
        </DataGrid.Columns>
    </DataGrid>
</Grid>

它可能没有数据上下文,但它仍然支持数据绑定,不是吗?在绑定文本到列(或按钮)时,同样的绑定表达式是否可以像任何其他地方一样工作?抱歉,我不是WPF专家。 - Adam Rackis
@Adam Rackis:我认为问题与DataContext无关。我同意你的看法,我也看不出你在问题中的绑定不起作用的原因。我尝试了很多不同的方法来让它工作,但是当使用RelativeSource或ElementName时它们都失败了。 - Fredrik Hedblad
1
嗯,看来不只有我一个人遇到这个问题了,希望能有所突破。如果可能的话,我不想在代码后台把这些东西拼接起来。 - Adam Rackis
@Adam Rackis:澄清我的评论。这与“Button”的DataContext无关。 - Fredrik Hedblad
谢谢更新。可能要等到周一早上我才能回复 - 再次感谢! - Adam Rackis
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接