具有两个控件的视图,绑定到相同的数据

时间:2013-01-04 13:16:18

标签: .net wpf mvvm caliburn.micro

我想知道如何使用两个ItemsControl获得一个视图,绑定到相同的视图模型。

这就是我所拥有的:

的ViewModels:

  • MonitoredItemViewModel.cs
  • MonitoredItemsViewModel.cs (包含属性BindableCollection MonitoredItems和一些命令)

查看:

  • MonitoredItemView.xaml
  • MonitoredItemsView.xaml (使用两个不同的控件显示MonitoredItemViewModel的集合)

在我的MonitoredItemsView.xaml中,我希望有一个WpfToolkit DataGrid来显示MonitoredItems - 集合中每个对象的详细信息,以及ItemsControl我要显示相同数据的内容,但以不同的方式(根据MonitoredItemView.xaml)

通过设置

<wtk:DataGrid x:Name="MonitoredItems" Height="Auto" AutoGenerateColumns="False" HorizontalAlignment="Stretch" Margin="0" Width="Auto" VerticalAlignment="Stretch">
...
</wtk:DataGrid>

Caliburn.Micro根据名称为数据网格解决了这个问题。

如何让我的ItemsControl绑定到相同的数据? 绑定通过设置

起作用
<ItemsControl ItemsSource="{Binding MonitoredItems, Mode=TwoWay}">
...
</ItemsControl>

但是我没有得到Caliburn.Micro-magic根据 MonitoredItemView.xaml

对每个项目进行模板化

2 个答案:

答案 0 :(得分:1)

好的,我会尝试在这里回答,但我承认我之前没有使用过Caliburn.Micro。

如果视图中有两个ItemsControls,并且您希望它们绑定到单个视图模型对象中的同一个集合,那么标准绑定机制将起作用。可以将多少个控件绑定到同一属性没有(实际)限制。

如果您希望每个控件以不同方式显示数据,则接受的方法是使用ItemTemplate覆盖ItemsControl的{​​{1}},然后根据您的需要布置数据。这些DataTemplate可以放在一个单独的资源字典中重复使用。

答案 1 :(得分:1)

您可以使用Bind.Model附加属性

e.g。

<ItemsControl ItemsSource="{Binding MonitoredItems, Mode=TwoWay}" cal:Bind.Model="{Binding PathToVMToBindTo}">
    ....
</ItemsControl>
然后,CM将使用ViewModelBinder

应用它的约定

如果有疑问,请阅读CodePlex网站上的CM文档(与许多其他项目相比,它们非常简洁)并检查源代码:

http://caliburnmicro.codeplex.com/wikipage?title=All%20About%20Conventions&referringTitle=Documentation

以下是Caliburn Micro Model类的Bind附加属性:

/// <summary>
///   Hosts dependency properties for binding.
/// </summary>
public static class Bind
{
    /// <summary>
    ///   Allows binding on an existing view. Use this on root UserControls, Pages and Windows; not in a DataTemplate.
    /// </summary>
    public static DependencyProperty ModelProperty =
        DependencyProperty.RegisterAttached(
            "Model",
            typeof(object),
            typeof(Bind),
            new PropertyMetadata(null, ModelChanged)
            );

    static void ModelChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if (Execute.InDesignMode || e.NewValue == null || e.NewValue == e.OldValue)
        {
            return;
        }

        var fe = d as FrameworkElement;
        if (fe == null)
        {
            return;
        }

        View.ExecuteOnLoad(fe, delegate
        {
            var target = e.NewValue;
            var containerKey = e.NewValue as string;

            if (containerKey != null)
            {
                target = IoC.GetInstance(null, containerKey);
            }

            d.SetValue(View.IsScopeRootProperty, true);

            var context = string.IsNullOrEmpty(fe.Name)
                              ? fe.GetHashCode().ToString()
                              : fe.Name;

            ViewModelBinder.Bind(target, d, context);
        });
    }