2010-09-10 4 views
1

J'ai une collection dans la fenêtre principale et je veux l'afficher sur une grille dans un utilisateur Contrôlez, Quelle est la bonne façon MVVM de faire cela?Reliure Observable collection

J'ai effectué un observableCollection dans la MainWindow et l'ai lié à un observableCollection dans le contrôle usercontrol. et dans le contrôle de l'utilisateur, la grille est limitée à la collection.

il ne fonctionne pas :(

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

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> 

+0

Vous pouvez publier un petit exemple du code. Il y a plusieurs raisons pour lesquelles cela pourrait ne pas fonctionner. Assurez-vous que vous définissez le DataContext correctement. Assurez-vous que votre ItemsSource est liée correctement, etc. – Robaticus

+0

Avez-vous regardé cette question SO? http://stackoverflow.com/questions/712398/silverlight-binding-with-observablecollections –

+0

Un drapeau rouge - vous avez une collection dans la fenêtre principale? La façon "MVVM" de le faire est d'avoir la collection dans le ViewModel. –

Répondre

8

La "bonne façon" de faire cela va exiger trois choses:

  • MainWindow
  • UserControl
  • ViewModel

Dans le ViewModel, vous voulez créer votre ObservableCollection et le définir comme une propriété sur le ViewModel, comme ceci:

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

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

Puis, dans la méthode Initialize de votre UserControl vous voulez instancier le ViewModel et l'attacher à la DataContext pour cette UserControl:

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

Note: Ceci est beaucoup plus facile Si vous utilisez un conteneur IoC pour gérer les résolutions de dépendance pour vous, mais par souci de simplicité, je saute cela ici.

Dans votre UserControl vous souhaitez spécifier le DataContext pour le UserControl, puis les liaisons individuelles pour votre DataGrid et les colonnes:

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

A partir de là, il vous suffit d'ajouter le UserControl à votre MainWindow.

Questions connexes