绑定集合中的控件

时间:2011-09-14 17:38:30

标签: c# wpf xaml data-binding

我有一个可互换视图的WPF应用程序。视图继承自我的ViewBase类:

public class ViewBase : ContentControl, IView
{
    public ViewBase()
    {
        ToolbarGroups = new ObservableCollection<ToolbarGroup>();
    }

    public ObservableCollection<ToolbarGroup> ToolbarGroups
    {
        get { return (ObservableCollection<ToolbarGroup>)GetValue(ToolbarGroupProperty); }
        private set { SetValue(ToolbarGroupProperty, value); }
    }

    public static readonly DependencyProperty ToolbarGroupProperty = 
                DependencyProperty.Register("ToolbarGroup", typeof(ObservableCollection<ToolbarGroup>), typeof(ViewBase));
}

我将ToolbarGroups属性绑定到窗口中的ItemsControl。它很棒。

ToolBarGroup继承自HeaderedContentControl,我将它们连接到这样的视图中:

<base:ViewBase x:Class="TestApp.Orders.OrderDetailsView"
               xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
               xmlns:base="clr-namespace:TestApp"
               xmlns:local="clr-namespace:TestApp.Orders"
               xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
               xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
               x:Name="root">

    <base:ViewBase.ToolbarGroups>
        <base:ToolbarGroup Header="Group1">
            <!-- Buttons and other controls go here -->
        </base:ToolbarGroup>

        <!-- Binding to MyProp is the problem -->
        <local:PremadeToolbarGroup MyProp="{Binding}" />

        <!-- This also doesn't work -->
        <local:PremadeToolbarGroup MyProp="{Binding ElementName=root,Path=DataContext}" />
    </base:ViewBase.ToolbarGroups>

        <Grid>
            <!-- this binding works -->
            <TextBox Text="{Binding Path=Model.FullName}" />
        </Grid>
</base:ViewBase>

PremadeToolbarGroup是一个继承自ToolbarGroup的XAML文件,并添加了一些按钮。 PremadeToolbarGroup包含一个名为MyProp的依赖项属性,我想将其绑定到其使用的视图的DataContext上。

我的DataContext设置为ViewModelBase类型的对象,它也是MyProp依赖项属性的类型。

PremadeToolbarGroup按预期显示,但绑定永远不会起作用(MyProp始终为null)。有什么想法吗?

2 个答案:

答案 0 :(得分:0)

DataContext是否在任何地方设置?尝试将DataContext = this添加到构造函数中。

答案 1 :(得分:0)

我找到了解决方案:

在我的窗口中,视图显示在ContentPresenter中:

<ContentPresenter Margin="3" x:Name="ViewPresenter" />

通过代码隐藏将content属性设置为View。

正如我在我的问题中所说,“我正在将ToolbarGroups属性绑定到窗口中的ItemsControl。”

所以我在窗口的其他地方显示ToolbarGroups:

<ItemsControl ItemsSource="{Binding ElementName=ViewPresenter, Path=Content.ToolbarGroups}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel Orientation="Horizontal" />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
</ItemsControl>

ToolbarGroup对象无法绑定到View的DataContext,因为它们已添加到视图外的可视树中。

我能够通过将ItemsControl中每个项的DataContext绑定到ViewPresetner内容的DataContext来修复它。它看起来像这样:

<ItemsControl ItemsSource="{Binding ElementName=ViewPresenter, Path=Content.ToolbarGroups}">
    <ItemsControl.ItemContainerStyle>
        <Style>
            <Setter Property="FrameworkElement.DataContext" Value="{Binding ElementName=ViewPresenter,Path=Content.DataContext }"/>
        </Style>
    </ItemsControl.ItemContainerStyle>
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel Orientation="Horizontal" />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
</ItemsControl>

它有点乱,但它有效。如果有人的话,我当然愿意接受更优雅的解决方案。