绑定Observable集合

时间:2010-09-10 12:21:11

标签: wpf silverlight mvvm

我在主窗口中有一个集合,我想在用户Control的网格上显示它, 什么是正确的MVVM方法呢?

我在MainWindow中完成了一个observableCollection,并将其绑定到usercontrol中的observableCollection。并且在用户控件中,网格是有界的 集合。

它不起作用:(

/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
    public ObservableCollection<string> MyNames
    {
        get { return (ObservableCollection<string>)GetValue(MyNamesProperty); }
        set { SetValue(MyNamesProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Names.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty MyNamesProperty =
        DependencyProperty.Register("MyNames", typeof(ObservableCollection<string>), typeof(MainWindow), new UIPropertyMetadata(null));

    public MainWindow()
    {
        MyNames = new ObservableCollection<string>() { "Jonh", "Mary" };
        this.InitializeComponent();
        DataContext = this;
    }
}

MainWindow XAML:

<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication3"
x:Class="WpfApplication3.MainWindow"
x:Name="Window"
Title="MainWindow"
UseLayoutRounding="True"
Width="640" Height="480">
<Grid>
    <local:NamesControl Names="{Binding MyNames}"></local:NamesControl>
</Grid>

用户控件:

  public partial class NamesControl : UserControl
{
    public ObservableCollection<string> Names
    {
        get { return (ObservableCollection<string>)GetValue(NamesProperty); }
        set { SetValue(NamesProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Names.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty NamesProperty =
        DependencyProperty.Register("Names", typeof(ObservableCollection<string>), typeof(NamesControl), new UIPropertyMetadata(null));



    public NamesControl()
    {
        InitializeComponent();
        DataContext = this;
    }
}

UserControl XAML:

<UserControl x:Class="WpfApplication3.NamesControl"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">
<Grid>
    <ItemsControl ItemsSource="{Binding Names}"/>
</Grid>

1 个答案:

答案 0 :(得分:8)

这样做的“正确方法”需要三件事:

  • 主窗口
  • 用户控件
  • 视图模型

在ViewModel中,您要创建ObservableCollection并将其设置为ViewModel上的属性,如下所示:

public class MyListViewModel
{
  public MyViewModel()
  {
    MyObjects = new ObservableCollection<MyObject>();
    // Add items to collection 
  }

  public ObservableCollection<MyObject> MyObjects{ get; set; }
}

然后,在UserControl的Initialize方法中,您希望实例化ViewModel并将其附加到该UserControl的DataContext:

public AgentListView()
{
      InitializeComponent();
      DataContext = new MyViewModel();
}

注意:如果您使用IoC容器为您处理依赖项解析,这会更容易,但为了简单起见,我在此处跳过这一点。

在UserControl中,您要为UserControl指定DataContext,然后为DataGrid和列指定单独的Binding:

<UserControl x:Class="UserControls.Views.AgentDataGridView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:toolkit="http://schemas.microsoft.com/wpf/2008/toolkit" 
             xmlns:utility="clr-namespace:UserControls.Utility"
             mc:Ignorable="d" 
             d:DataContext="{Binding}">
  <GroupBox Header="Agent States" Height="auto" Margin="0,5,0,0" Name="_groupBox" VerticalAlignment="Top" BorderBrush="DarkSlateBlue">
    <Grid Name="_grid" ShowGridLines="True" Margin="5" >
      <toolkit:DataGrid 
        ItemsSource="{Binding MyObjects, Mode=OneWay}">
        <toolkit:DataGrid.Columns>
          <toolkit:DataGridTextColumn Binding="{Binding StateAndJobDescription, Mode=OneWay, NotifyOnSourceUpdated=True,UpdateSourceTrigger=PropertyChanged}" Header="State" Width="100" IsReadOnly="True" />
          <toolkit:DataGridTextColumn Binding="{Binding SubStateDescription, Mode=OneWay, NotifyOnSourceUpdated=True,UpdateSourceTrigger=PropertyChanged}" Header="City" Width="120" IsReadOnly="True" />
        </toolkit:DataGrid.Columns>
      </toolkit:DataGrid>
    </Grid>
  </GroupBox>
</UserControl>

从这里开始,您只需将UserControl添加到MainWindow即可。