52

我们有一个带有标准 MVVM 模式的 WPF 应用程序,利用 Cinch(以及因此 MefedMVVM)进行 View -> ViewModel 分辨率。这很好用,我可以将相关控件绑定到 ViewModel 上的属性。

在特定视图中,我们有一个 Infragistics XamGrid。此网格绑定到 ViewModel 上的 ObservableCollection,并显示相应的行。但是,然后我在此网格上有一个特定列,我试图将 TextBox 文本值绑定到父 DataContext 上的属性,而不是 ObservableCollection。此绑定失败。

我们在这里经历了几个选项,包括:

  1. 使用 AncestorType 跟踪树并像这样绑定到父 UserControl 的 DataContext (来自这个问题的好答案,以及这个)......

    {Binding Path=PathToProperty, RelativeSource={RelativeSource AncestorType={x:Type typeOfAncestor}}}
    
  2. 指定 ElementName 并尝试直接定位顶级控件。如果您想了解如何使用 ElementName,请查看此处。

  3. 使用在资源中为 UserControl 定义的“代理”FrameorkElement 尝试根据需要“传入”上下文。我们将元素定义如下,然后作为静态资源引用...

    <FrameworkElement x:Key="ProxyContext" DataContext="{Binding Path=DataContext, RelativeSource={RelativeSource Self}}"></FrameworkElement>
    

在这种情况下,绑定会找到 FrameworkElement,但无法访问除此之外的任何内容(指定路径时)。

仔细阅读后,这很可能是由 Infragistics XamGrid 在树外构建列引起的。但是,即使是这种情况,至少选项 2 或 3 应该有效。

我们最后的想法是它与 V - VM 绑定有关,但即使使用 Snoop,我们还没有找到确切的问题。我绝不是 WPF 绑定方面的专家,所以任何指针都将不胜感激。

编辑:我在这里找到了一些来自 Infragistics 的模板示例,我将尝试。

编辑2:正如@Dtex 所指出的,模板是要走的路。以下是与 XamGrid 一起使用的相关代码段:

<ig:GroupColumn Key="CurrentDate">
                <ig:GroupColumn.HeaderTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Path=DataContext.CurrentDateTest, RelativeSource={RelativeSource AncestorType=UserControl}}" />
                    </DataTemplate>
                </ig:GroupColumn.HeaderTemplate>
                <ig:GroupColumn.Columns>

我已将 XML 保持打开状态...您只需添加所需的列,然后关闭相关标签。

4

2 回答 2

96

我不知道,XamGrid但这就是我将使用标准 wpf 做的事情DataGrid

<DataGrid>
    <DataGrid.Columns>
        <DataGridTemplateColumn>
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding DataContext.MyProperty, RelativeSource={RelativeSource AncestorType=MyUserControl}}"/>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
            <DataGridTemplateColumn.CellEditingTemplate>
                <DataTemplate>
                    <TextBox Text="{Binding DataContext.MyProperty, RelativeSource={RelativeSource AncestorType=MyUserControl}}"/>
                </DataTemplate>
            </DataGridTemplateColumn.CellEditingTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>

由于单元格模板中指定的TextBlockTextBox将成为可视化树的一部分,因此您可以向上找到所需的任何控件。

于 2012-11-16T13:15:16.580 回答
0

由于这样的事情,作为一般的经验法则,我尽量避免 XAML 的“诡计”,并使 XAML 尽可能简单和简单,并在 ViewModel(或附加属性或 IValueConverters 等)中完成其余的工作。如果真的有必要)。

如果可能的话,我会给当前 DataContext 的 ViewModel 一个对相关父 ViewModel 的引用(即属性)

public class ThisViewModel : ViewModelBase
{
    TypeOfAncestorViewModel Parent { get; set; }
}

并直接与之绑定。

<TextBox Text="{Binding Parent}" />

于 2012-11-16T11:39:54.670 回答