Как получить данные в ViewModel UserControl? - PullRequest
0 голосов
/ 24 марта 2012

Новое в WPF / MVVM.У меня есть объект данных типа «MyData».Одно из его свойств имеет тип «MySubsetData».

Я показываю коллекцию объектов «MyData» в сетке данных.

<DataGrid ItemsSource="{Binding Path=MyDataCollection}">
    <!-- Each row of the datagrid contains an item of type "MyData" -->
    <DataGrid.Columns .../>
    <DataGrid.RowDetailsTemplate>
        <DataTemplate>
            <local:MySubsetDataUserControl/>
        </DataTemplate>
    </DataGrid.RowDetailsTemplate>
</DataGrid>

В деталях строки должно отображаться содержимое «MySubsetData»,Представление сведений о строке находится в отдельном пользовательском элементе управления (здесь: «MySubsetDataUserControl»).

В настоящее время я не устанавливаю модель представления для «MySubsetDataUserControl», поэтому он наследует контекст данных отСтрока таблицы данных родителя.

<UserControl>
    <!-- Namespace stuff not shown for simplicity -->
    <Grid DataContext="{Binding Path=MySubsetData}">
        <!-- Show the MySubsetData properties here -->
        <!-- e.g. a textbox -->
            <TextBox Text="{Binding Path=TextData, UpdateSourceTrigger=PropertyChanged}"/>
    </Grid>
</UserControl>

Хотя это работает, я сталкиваюсь с несколькими проблемами с этим подходом:

  1. Вся бизнес-логика будет в модели представления родительского элемента управления пользователя,где это просто не принадлежит.Делая модель представления более грязной, чем она должна быть.Не говоря уже о том, что привязки команд в пользовательском элементе управления xaml также выглядят очень некрасиво.Это просто нехорошо.

  2. Поскольку одновременно можно увидеть больше деталей строки, я не могу связать свойства «MySubsetData» с наблюдаемым свойством в представлениимодель.Т.е., если я изменю свойство в коде (например, TextData), изменение не будет отражено в представлении.Мой обходной путь - не изменять свойство «TextData».Вместо этого я изменяю содержимое текстового свойства Textbox, которое, в свою очередь, обновляет свойство «TextData».И это кажется очень неправильным!

Так что я хотел бы использовать другую модель представления для моего пользовательского контроля, но тогда я не знаю, как получить доступ к моим данным.

<UserControl.DataContext>
    <local:UserControlViewModel/>
</UserControl.DataContext>

Как получить доступ к «MySubsetData» сейчас?

1 Ответ

0 голосов
/ 24 марта 2012

Предположим, у вас есть модель вида, подобная этой:

public class ViewModel
{
    public IEnumerable<MyData> MyDataCollection{get; private set;}
}

Где

public class MyData
{
    public MySubsetData MySubsetData { get; }
}

Ваше представление, содержащее сетку данных, будет

<UserControl.DataContext>
    <local:ViewModel>
</UserControl.DataContext>

<DataGrid ItemsSource="{Binding Path=MyDataCollection}">
    <DataGrid.Columns .../>
    <DataGrid.RowDetailsTemplate>
        <DataTemplate> 
            <!-- each row of the items control has an implicit DataContext of MyData -->
            <!-- so bind the DataContext of the subset control to MySubsetData -->
            <local:MySubsetDataUserControl DataContext={Binding MySubsetData}/>
        </DataTemplate>
    </DataGrid.RowDetailsTemplate>
</DataGrid>

Теперь вашуправление подмножеством может выглядеть как

<UserControl>
    <Grid>
        <TextBox Text="{Binding Path=TextData, UpdateSourceTrigger=PropertyChanged}"/>
    </Grid>
</UserControl>

Перечитывая вопрос, возможно, все, что я сделал, это повторил Xaml из вопроса немного по-другому.

Однако различные классыдолжен реализовывать INotifyPropertyChanged, например,

public class MySubsetData : INotifyPropertyChanged
{
   public string TextData
   {
      get{...}
      set{...; OnPropertyChanged("TextData"); }
   }
}

Тогда TextBox, связанный со свойством TextData, будет отражать изменения, сделанные в коде.

...