代码之家  ›  专栏  ›  技术社区  ›  Erez

绑定可观察集合

  •  1
  • Erez  · 技术社区  · 15 年前

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

    我在主窗口中完成了一个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;
        }
    }
    

    主窗口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;
        }
    }
    

    用户控件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 回复  |  直到 15 年前
        1
  •  8
  •   Chris Holmes    15 年前

    要做到这一点,“正确的方法”需要三件事:

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

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

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

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

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

    注意:如果您使用IOC容器为您处理依赖关系解析,那么这就容易得多,但是为了简单起见,我在这里跳过了这一点。

    在UserControl中,要为UserControl指定DataContext,然后为DataGrid和列指定各个绑定:

    <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>
    

    从这里,您只需要将用户控件添加到主窗口中。