绑定到当前ItemsSource上下文之外的DataContext

时间:2010-10-13 00:34:11

标签: wpf data-binding datagrid itemssource relativesource

DataSet绑定了Window.DataContext;我还有DataGrid

<DataGrid ItemsSource={Binding Tables[Items]}>
    <DataGrid.Columns>
        <DataGridTextBoxColumn Header={Binding Path=DataContext.Tables[Names]/Test, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}} />
    </DataGrid.Columns>
</DataGrid>

基本上,我正在尝试将该列的Header绑定到DataTable“Names”,列“Test”,第一行。

然而,我无法做对。请注意,我可以在DataGrid外部绑定它。 Grid的ItemsSource更改了数据上下文,我不知道如何在外部引用原始DataContext。

似乎绑定成功了;但问题是Window.DataContext中Tables [Names]的当前项(第一行)丢失了。

如果我将DataSet设为静态并通过{x:Static local:dataset}访问它,那么一切正常。但是我不能使用静态数据集,因为会有多个实例(多用户)。

任何人都可以指出我正确的方向吗?

3 个答案:

答案 0 :(得分:12)

我很确定你可以使用RelativeSource绑定来做你想做的事。

<DataGrid ItemsSource="{Binding StringCollection}" 
          AutoGenerateColumns="False">
  <DataGrid.Columns>
    <DataGridTextColumn Binding="{Binding}" />
    <DataGridTextColumn Binding="{
                          Binding RelativeSource={
                            RelativeSource FindAncestor, 
                            AncestorType={x:Type Window}},
                          Path=DataContext.SomethingOutsideDataContext}" />
  </DataGrid.Columns>
</DataGrid>

我在http://bitbucket.org/claus/wpf-bindingoutsidedatacontext

做了一个简单的例子

它允许你绑定到父窗口,在我的例子中,它将viewmodel作为datacontext(上面有SomethingOutsideDataContext属性)。

你应该知道,这只适用于WPF,而不适用于Silverlight - “FindAncestor,AncestorType”的东西还没有在Silverlight中实现......我不确定是否还有另一种方法,除了使用静态资源

答案 1 :(得分:0)

不知道这是否适用于您的情况,但您可以尝试这样的事情: 1)给你的窗口一个名字属性,例如NAME = ZeWindow。 2)绑定你的DataGridTextBoxColumn标题:

<DataGridTextBoxColumn Header="{Binding Path=DataContext.Tables[Names]/Text, ElementName=ZeWindow}"/>

基本上,不是绑定到DataContext的{​​{1}},而是使用Name = ZeWindow绑定到DataGrid的{​​{1}}。

P.S。:我对WPF很新,所以这可能不适用于Window,但我使用UserControls做了类似的事情

答案 2 :(得分:0)

这实际上是预期的行为:DataContex的{​​{1}} t是整个行。

所以你有3个解决方案: 要么在代码后面添加绑定,请执行以下操作:

在每个Column的构造函数中:

DataGridCell

(你必须找到一种获取“thisColumnIndex”的方法。就我而言,我在创建它之后立即添加列,我只是将“dataGridOwner.Columns.Count”放在那里)。 / p>

...或

你可以找到一种方法来获取你想要的每个单元格上的dataContext(试过但是当列/行虚拟化打开时它会很糟糕)

...或

看看那里:

Binding a cell object's property to a DataGridCell in WPF DataGrid

我个人认为第一个更适合我的目的(因为我无论如何都要在代码后面添加我的列),但这最终取决于你...


就columnHeaders而言(并且只有columnsHeaders而不是行),您也可以探索“DataTemplate”方式:

将列的标题设置为Column本身(这样您将列设置为标题的DataContext)并使用DataTemplate。

e.g:

在每个列类中:

string source = String.Format(CultureInfo.InvariantCulture, "[{0}].", thisColumnIndex);
base.Binding = new Binding(source + "Text");

并在您的dataGrid的xaml中,类似于:

private static DependencyProperty ColumnHeaderProperty = DependencyProperty.Register("ColumnHeader", typeof(MyDataGridColumnHeader), typeof(MyTextBoxColumn));
public MyDataGridColumnHeader ColumnHeader
{
    get { return (MyDataGridColumnHeader)(GetValue(ColumnHeaderProperty)); }
    set { SetValue(ColumnHeaderProperty, value); }
}

this.ColumnHeader = new MyDataGridColumnHeader();
Header = this;

当然,我的“MyDataGridColumnHeader”类包含此处引用的所有属性的定义。

希望这会有所帮助。