WPF绑定到ItemsControl中的ElementName

时间:2010-09-20 17:08:38

标签: wpf binding

我有一个复选框,以及以下列方式填充多个DataGrids的ItemsControl:

<Checkbox Content="Birthday Column Visible" x:Name="UI_BirthdayVisibleCB" />

<ItemsControl  ItemsSource="{Binding Path=ParentsCollection}">
   <ItemsControl.ItemTemplate>
      <DataTemplate>
         <DataGrid  AutoGenerateColumns="False" ItemsSource="{Binding Children}">
            <DataGrid.Columns>
                <DataGridTemplateColumn Header="Birthday" Width="120" Visibility="{Binding IsChecked, ElementName=UI_BirthdayVisibleCB, Converter={StaticResource BoolToVis}}" >
...
               </DataGridTemplateColumn>
            </DataGrid.Columns>
         </DataGrid>
</Rest of closing tags>

这会在尝试在DataGridTemplateColumn上查找IsChecked时创建绑定输出错误。如果我尝试搜索相对祖先,我会收到异常:

Binding.RelativeSource cannot be set while using Binding.ElementName.

我有一个ViewModel,并且主要坚持使用MVVM,但在这种情况下,我真的希望保持View层上的列可见性。请注意,BoolToVis只会将布尔值转换为可见性。

修改

以下是我正在尝试做的一个例子:

 <DataGridTemplateColumn Header="Birthday" Visibility="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:MyView} }, Path=IsChecked, ElementName=UI_BirthdayVisibleCB, Converter={StaticResource BoolToVis}}" />

它编译但不运行,但它会引发上面的异常。

2 个答案:

答案 0 :(得分:11)

您使用的是RelativeSource,它不能与ElementName混合使用,但是一旦拥有了正确的RelativeSource,您就可以使用路径深入钻取。

e.g。

Visibility="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:MyView} }, Path=UI_BirthdayVisibleCB.IsChecked, Converter={StaticResource BoolToVis}}"

大概你有一些这样的xaml:

<UserControl class="MyView" ... >...<CheckBox Name="UI_BirthdayVisibileCB"/> ...

上面的绑定应该根据RelativeSource找到这个UserControl类型,然后它会尝试找到一个名为UI_BirthdayVisibleCB的属性,它找不到它,因为WPF XAML将这个命名元素作为一个字段来实现。

简单的解决方法是进入代码隐藏并为其公开属性。

public object BirthdayVisibileCB_4_binding {
    get { return UI_BirthdayVisibileDB; }
}

然后绑定到它:

Visibility="{Binding RelativeSource={RelativeSource FindAncestor, 
AncestorType={x:Type local:MyView} }, 
Path=BirthdayVisibileCB_4_binding.IsChecked, Converter={StaticResource BoolToVis}}"

是的,这样做有点痛苦,但MVVM到目前为止仅匹配WPF ......它不是很合适,它只是我们最合适的。

答案 1 :(得分:3)

如果您想尝试RelativeSource,则必须从声明中删除ElementName

  然而,只有三个中的一个   properties,ElementName,Source和   RelativeSource,应该为每个设置   可能会发生绑定或冲突。   如果属性,此属性将引发异常   存在绑定源冲突。

http://msdn.microsoft.com/en-us/library/system.windows.data.binding.elementname.aspx

您对ElementName的使用似乎是正确的,因此如果您愿意超过RelativeSource,我会继续查看问题。