你好,我有一个应用程序设计问题,我回家你可以帮我解决它.... 这是我在silverlight中的第一个应用程序和使用mvvm设计模式的第一个应用程序,我不确定我是应该使用mvvm我应该如何...
应用程序是一个动态应用程序,在运行时我可以添加/删除usercontrols ......
所以我有一个MainWindowModel后面的MainWindowView。
MainWindowModel有一个工作区列表,实际上是WorkspaceModel类......
我有多个UserControls,他们的每个人都有自己的视图模型继承WorkspaceModel。
Workspaces属性绑定到MainWindowView中的容器,因此添加到Workspaces列表中的新UserControlModel将自动将该控件添加到视图中。 现在我的问题在哪里...我想让这个动态添加的usercontrols进行交互。让我们说一个用户控件是树,一个是网格......我想要一个方法来说明Grid UserControl Model(WorkspaceModel)的Itemsource属性要绑定到Tree Usercontrol Model(WorkspaceModel)中的SelectedNode.Nodes属性。 / p>
MainWindowModel有一个属性名称BindingEntries,它有一个BindingEntry列表... BindingEntry存储绑定的source属性和destination属性,如我的workspacemodel_1.SelectedNode.Nodes - > workspacemodel_2.ItemSource ...
或者作为变体,MainWindowView具有属性ViewStateModel。此ViewStateModel类具有动态创建的属性 - “注入”属性类型描述符/反射等...因此用户可以在运行时定义显示的用户控件(通过修改工作空间列表)并可以定义视图模型(ViewStameModel)和绑定是在workspacemodel属性和此ViewStateModel属性之间...
所以我实际上想要将2个视图模型彼此绑定...怎么做? 创建一个观察者模式? 设计到现在为止完全错了吗?
我希望它有意义.....
我会尝试添加一些示例代码...项目非常大我会尝试co只把我在问题解决中提到的部分...我希望我不会错过任何代码p /
首先
public class MainWindowModel : ModelBase
{
private ObservableCollection<WorkspaceModel> _workspaces;
private ModelBase _userViewModel;
public MainWindowModel()
{
base.DisplayName = "MainWindowModel";
ShowTreeView(1);
ShowTreeView(2);
ShowGridView(3);
ShowGridView(4);
UserViewModel = new ViewModel(); //this is the ViewStateModel
}
void ShowTreeView(int id)
{
WorkspaceModel workspace = ControlFactory.CreateModel("TreeControlModel", id);
this.Workspaces.Add(workspace);
OnPropertyChanged("Workspaces");
SelectedWorkspace = workspace;
}
void ShowGridView(int id)
{
WorkspaceModel workspace = ControlFactory.CreateModel("GridControlModel", id);
this.Workspaces.Add(workspace);
OnPropertyChanged("Workspaces");
SelectedWorkspace = workspace;
}
public ObservableCollection<WorkspaceModel> Workspaces
{
get
{
if (_workspaces == null)
{
_workspaces = new ObservableCollection<WorkspaceModel>();
}
return _workspaces;
}
}
public ModelBase UserViewModel
{
get
{
return _userViewModel;
}
set
{
if (_userViewModel == value)
{
return;
}
_userViewModel = value;
OnPropertyChanged("UserViewModel");
}
}
}
来自MainappView的片段
<DataTemplate x:Key="WorkspaceItemTemplate">
<Grid >
//workaround to use Type as in WPF
<Detail:DetailsViewSelector Content="{Binding}" TemplateType="{Binding}" >
<Detail:DetailsViewSelector.Resources>
<DataTemplate x:Key="TreeControlModel" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >
<TreeControl:TreeControlView />
</DataTemplate>
<DataTemplate x:Key="GridControlModel" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >
<GridControl:GridControlView />
</DataTemplate>
<DataTemplate x:Key="EmptyTemplate">
</DataTemplate>
</Detail:DetailsViewSelector.Resources>
</Detail:DetailsViewSelector>
</Grid>
</DataTemplate>
<DataTemplate x:Key="WorkspacesTemplate">
<ItemsControl IsTabStop="False" ItemsSource="{Binding}" ItemTemplate="{StaticResource WorkspaceItemTemplate}" Margin="6,2"/>
</DataTemplate>
</UserControl.Resources>
<toolkit:HeaderedContentControl Grid.Column="2" HorizontalAlignment="Stretch" Name="hccWorkspaces" VerticalAlignment="Top" Header="Workspaces" Content="{Binding Source={StaticResource vm}, Path=Workspaces}" ContentTemplate="{StaticResource WorkspacesTemplate}"/>
public class ControlFactory
{
public static WorkspaceModel CreateModel(string type, int id)
{
switch (type)
{
case "TreeControlModel": return new TreeControlModel() { Id=id}; break;
case "GridControlModel": return new GridControlModel() { Id = id }; break;
}
return null;
}
}
public class GridControlModel : WorkspaceModel
{
#region Fields
ObservableCollection<TreeItem> _items;
TreeItem _selectedItem;
#endregion // Fields
#region Constructor
public GridControlModel()
{
base.DisplayName = "GridControlModel";
}
#endregion // Constructor
#region Public Interface
public ObservableCollection<TreeItem> Items
{
get
{
return _items;
}
set
{
if (_items == value)
return;
_items = value;
OnPropertyChanged("Items");
}
}
public TreeItem SelectedItem
{
get
{
return _selectedItem;
}
set
{
if (_selectedItem.Equals(value))
{
return;
}
_selectedItem = value;
OnPropertyChanged("SelectedItem");
}
}
#endregion // Public Interface
#region Base Class Overrides
protected override void OnDispose()
{
this.OnDispose();
}
#endregion // Base Class Overrides
}
<Grid x:Name="LayoutRoot" Background="White">
<sdk:DataGrid Grid.Column="2" Grid.Row="1" HorizontalAlignment="Stretch" Name="dataGrid1" VerticalAlignment="Stretch" ItemsSource="{Binding Path=SelectedTreeNode.Children}" IsEnabled="{Binding}" AutoGenerateColumns="False">
<sdk:DataGrid.Columns>
<sdk:DataGridTextColumn CanUserReorder="True" CanUserResize="True" CanUserSort="True" Header="Id" Width="Auto" Binding="{Binding Id}" />
<sdk:DataGridTextColumn CanUserReorder="True" CanUserResize="True" CanUserSort="True" Header="Name" Width="Auto" Binding="{Binding Name}"/>
</sdk:DataGrid.Columns>
</sdk:DataGrid>
</Grid>
</UserControl>
答案 0 :(得分:0)
为了在您的视图模型之间进行通信,我建议您查看MVVM Light中的Messenger实现作为一个简单的解决方案。
或者,此处描述的Mediator Pattern可能很有趣:http://marlongrech.wordpress.com/2008/03/20/more-than-just-mvc-for-wpf/