【问题标题】:WPF DataGrid - Databinding Column to Page's ViewModelWPF DataGrid - 数据绑定列到页面的 ViewModel
【发布时间】:2011-02-18 20:51:29
【问题描述】:

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

我在下面推荐了here,但无济于事。

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

在我的视图模型中

public string JUNK { get; set; }

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

有人看到我做错了吗?

编辑

这是整个 XAML。相关列一直在底部,在网格内的网格中

ALSO - 我无法再次将我的整个源代码放到这里(不确定是 citrix 还是什么),但我采用了 完全相同的绑定表达式在 datagrid 的按钮中工作,我将它放到了一个远离网格的普通旧 TextBlock 的 Text 上,它就像一个魅力。我还在网格中添加了一个新的虚拟文本列,并为文本使用了相同的绑定表达式,它仍然 not 起作用。看起来这个绑定表达式很好,但拒绝在网格附近的任何地方工作。

<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”的元素,您已在该元素上将 DataContext 设置为您的 ViewModel?您能否发布更多 XAML(特别是“LayoutRoot”元素的定义)?谢谢!
  • 我根本不是 WPF 专家,但 LayoutRoot 不是内置的 - 这不是自动成为范围内最顶层的 UI 元素吗?或者这完全是错误的,我需要将 LayoutRoot 的名称添加到所述 UI 元素?其实我看得很清楚是这样的。只需将其写在答案中,我将关闭它。谢谢。
  • 实际上,不,它没有。我确信它会的。现在更新问题...
  • +1,非常好的问题。我对这种行为感到非常惊讶,我发布的答案不是一个很好的解决方案,但这是我唯一能想到的。我不知道为什么它不能与 ElementName 或 RelativeSource 一起使用,但我会观察这个问题,看看是否有人对此提出了更好的解释或解决方法:)
  • @Adam Rackis:查看我的更新答案以了解解决方法

标签: c# wpf


【解决方案1】:

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

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

在嵌套 DataGrid 时,必须将 AncestorLevel 设置为“2”才能绑定到最外层 DataGrid 的 DataContext。

【讨论】:

  • 哇——就是这么简单。谢谢!
  • 哇哦,这真的帮助我使用视图模型绑定 +1 设置 DataGrid 列的样式。
【解决方案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 的实例作为DataGridColumns 中的绑定源

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

【讨论】:

  • 它可能没有数据上下文,但它仍然支持DataBinding,不是吗?在将文本绑定到列(或按钮)的列中,相同的绑定表达式不会像其他任何地方一样工作吗?再次抱歉,我不是 WPF 专家。
  • @Adam Rackis:我看到的问题与 DataContext 无关。我同意你的观点,我看不出有任何理由让你的问题中的绑定不起作用。我尝试了很多不同的方法来让它工作,但是在使用 RelativeSource 或 ElementName 时它们都失败了
  • 呸 - 我想这不仅仅是我 - 希望会出现一些事情。如果可能的话,我不想在后面的代码中把它串起来。
  • @Adam Rackis:澄清我的评论。与Button的DataContext无关
  • 好的 - 再次感谢您的帮助。一旦我能解决这个问题,我会以任何一种方式支持你的答案。
猜你喜欢
  • 2011-04-13
  • 2012-02-23
  • 2016-04-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-30
  • 1970-01-01
  • 2011-02-04
相关资源
最近更新 更多