Binding Observable collection
I have a collection in the main window and I want to show it on a grid in a user Control, What is the right MVVM way to do that ?
I've done an observableCollection in the MainWindow And bounded it to an observableCollection in the usercontrol. and in the user control the grid is bounded to the collection.
it doesn't work :(
/// <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(Ob开发者_开发百科servableCollection<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>
UserControl:
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>
The "right way" to do this is going to require three things:
- MainWindow
- UserControl
- ViewModel
In the ViewModel, you want to create your ObservableCollection and set it as a property on the ViewModel, like so:
public class MyListViewModel
{
public MyViewModel()
{
MyObjects = new ObservableCollection<MyObject>();
// Add items to collection
}
public ObservableCollection<MyObject> MyObjects{ get; set; }
}
Then, in your UserControl's Initialize method you want to instantiate the ViewModel and attach it to the DataContext for that UserControl:
public AgentListView()
{
InitializeComponent();
DataContext = new MyViewModel();
}
Note: this is much easier if you're using an IoC container to handle dependency resolutions for you, but for simplicity sake I am skipping that here.
In your UserControl you want to specify the DataContext for the UserControl and then the individual Bindings for your DataGrid and the Columns:
<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>
From here, you just need to add the UserControl to your MainWindow.
精彩评论