我目前正在使用WPF应用程序,但有几个问题。到目前为止,我已经将所有业务逻辑放在一个ViewModel中,而我现在注意到的是ViewModel没有特定的上下文。
一个例子是:
<telerik:RadSplitContainer Orientation="Vertical" telerik:DockingPanel.InitialSize="750,200">
<telerik:RadPaneGroup IsContentPreserved="False" telerik:ProportionalStackPanel.RelativeSize="200,300" >
<telerik:RadPane
<ContentControl ContentTemplate="{StaticResource CategoryTemplate}"
Content="{Binding CategoryViewModel}" />
</telerik:RadPane>
</telerik:RadPaneGroup>
<telerik:RadPaneGroup IsContentPreserved="False" telerik:ProportionalStackPanel.RelativeSize="100,120">
<telerik:RadPane Header="Items list"
CanUserClose="False" CanUserPin="False"
CanDockInDocumentHost="True">
<ContentControl ContentTemplate="{StaticResource ItemsListTemplate}"
Content="{Binding ItemsViewModel}" />
</telerik:RadPane>
</telerik:RadPaneGroup>
</telerik:RadSplitContainer>
但是,这是mainwindows.xaml的样子,它是由指定为数据模板的多个视图构建的。此时,我决定从庞大的通用视图模型中提取业务逻辑,并为每个视图创建一个视图模型。
我有两种视图,一种用于类别,一种用于与类别相对应的项目。这两个视图包含一个gridview,该网格视图显示CategoryView中的类别以及与该类别相对应的项目。
包含所有项目的viewmodel最初为空,类别仅从DB中检索所有现有类别。在CategoryViewModel中也有一个SelectedCategory,其中包含我选择的网格行项目。
我想做的是在categoryView的网格中选择一行,我希望CategoryViewModel告诉ItemsViewModel检索与我从CategoryViewModel检索到的categoryID相对应的项。然后使用INotifyPropertychanged刷新itemsViewModel中的itemscollection,并刷新网格上的视图。
我的mainView视图和视图模型:
public MainViewModel()
{
this.InitializeCommands();
this.ItemsViewModel = new ItemsViewModel();
this.CategoryViewModel = new CategoryViewModel();
}
public ViewModelBase CategoryViewModel
{
get { return this._categoryViewModel; }
set
{
if (this._categoryViewModel != value)
{
this._categoryViewModel = value;
}
}
}
public ViewModelBase ItemsViewModel
{
get
{
if (this._itemsViewModel == null)
{
this._itemsViewModel;
}
return this._itemsViewModel;
}
set
{
if (this._itemsViewModel != value)
{
this._itemsViewModel = value;
}
}
}
MainView中使用的另一个视图数据模板的示例:
<DataTemplate x:Key="NewsTemplate">
<Grid Margin="10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<telerik:RadBusyIndicator x:Name="BusyIndicator">
<telerik:RadGridView Name="gridView"
ItemsSource="{Binding
Category}"
SelectedItem="{Binding SelectedCategory, Mode=TwoWay}">
<telerik:RadGridView.Columns>
<telerik:GridViewDataColumn DataMemberBinding={Binding Name}" Header="Name"/>
</telerik:RadGridView>
</telerik:RadBusyIndicator>
</Grid>
</DataTemplate>`
为项目添加了视图模型:
public ObservableCollection<Item> GetItems
{
get
{
this._getItems = GetFromDb.GetItems(CategoryID)
return this._getItems;
}
set
{
if (this._getItems != value)
{
this._getItems = value;
this.OnPropertyChanged("GetItems");
}
}
}
public QueryableCollectionView Items
{
get
{
return this._items = new QueryableCollectionView(GetItems(CategoryID));
}
set
{
if (this._items != value)
{
this._items = value;
this.OnPropertyChanged(() => Items);
}
}
}
MainViewModel(如果您查看的话,我有一个方法GetFromDb.GetItems(CategoryID)来检索项目):
public MainViewModel()
{
this.InitializeCommands();
this.CategoryViewModel = new CategoryViewModel();
this.ItemsViewModel = new ItemsViewModel();
this.CategoryViewModel.OnChanged += (s, e) => {
//this one?
this.ItemsViewModel.ContractMetaDatas(CategoryViewModel.ID)
//this one?
this.ItemsViewModel.ContractMetaDatas = new QueryableCollectionView(GetFromDb.GetItems(CategoryID));
};
}
我该如何实现?
答案 0 :(得分:0)
我想做的是在categoryView的网格中选择一行,我希望CategoryViewModel告诉ItemsViewModel检索与我从CategoryViewModel检索到的categoryID相对应的项。然后使用INotifyPropertychanged刷新itemsViewModel中的itemscollection,并刷新网格上的视图。
我该如何实现?
好吧,基本上,您可以对事件使用典型的设置:
从您的CategoryViewModel
中触发一个事件,并在整个容器中进行处理。
public class MainViewModel: INotifyPropertyChanged
{
public CategoryViewModel CategoryViewModel {get;set;}
public ItemsViewModel ItemsViewModel {get;set;}
public MainViewModel()
{
this.InitializeCommands();
this.ItemsViewModel = new ItemsViewModel();
this.CategoryViewModel = new CategoryViewModel();
//wire up the event
this.CategoryViewModel.OnChanged += (s,e) => {
//perform update here
this.ItemsViewModel.UpdateWithId(this.CategoryViewModel.SelectedId);
};
}
///...
}
类别:
public class CategoryViewModel : INotifyPropertyChanged
{
//fire this when appropiate
public event EventHandler OnChanged;
///...
}