Wpf 具有不同viewmodel的相同视图-prism
我不知道如何在标题中描述我的场景,所以请原谅我的标题不好 我的设想: 主视图:Wpf 具有不同viewmodel的相同视图-prism,wpf,mvvm,prism,Wpf,Mvvm,Prism,我不知道如何在标题中描述我的场景,所以请原谅我的标题不好 我的设想: 主视图: <Grid> <TabControl ItemsSource="{Binding Tabs}" SelectedIndex="0"> <TabControl.ItemTemplate> <DataTemplate> <TextBlock Text="{
<Grid>
<TabControl ItemsSource="{Binding Tabs}"
SelectedIndex="0">
<TabControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding ViewName}"/>
</DataTemplate>
</TabControl.ItemTemplate>
<TabControl.ContentTemplate>
<DataTemplate>
<ContentControl x:Name="SamplesContentControl"
Content="{Binding View}"
VerticalContentAlignment="Stretch"
HorizontalContentAlignment="Stretch"/>
</DataTemplate>
</TabControl.ContentTemplate>
</TabControl>
</Grid>
MainViewModel:
public class MainViewModel
{
public List<Tab> Tabs { get; set; }
IUnityContainer container;
public MainViewModel(IUnityContainer container)
{
this.container=container;
Tabs = new List<Tab>();
Tabs.Add(new Tab() { ViewName = "Test1", View = this.container.Resolve<TestView>() });
Tabs.Add(new Tab() { ViewName = "Test2", View = this.container.Resolve<TestView>() });
Tabs.Add(new Tab() { ViewName = "Test3", View = this.container.Resolve<TestView>() });
}
}
public class TestViewModel
{
public ObservableCollection<Test> Tests{ get; set; }
public TestViewModel(ITestDataService testDataService)
{
Tests= new ObservableCollection<Test>(testDataService.GetTests());
}
}
public类主视图模型
{
公共列表选项卡{get;set;}
i单元容器;
公共主视图模型(IUnityContainer容器)
{
this.container=container;
Tabs=新列表();
Tabs.Add(new Tab(){ViewName=“Test1”,View=this.container.Resolve()});
Tabs.Add(new Tab(){ViewName=“Test2”,View=this.container.Resolve()});
Tabs.Add(new Tab(){ViewName=“Test3”,View=this.container.Resolve()});
}
}
TestView是一个ListView,我希望这3个视图有不同的数据。例如,Test1视图包含Test1的数据,Test2View包含Test2的数据。但我不知道如何做到这一点
TestViewModel:
public class MainViewModel
{
public List<Tab> Tabs { get; set; }
IUnityContainer container;
public MainViewModel(IUnityContainer container)
{
this.container=container;
Tabs = new List<Tab>();
Tabs.Add(new Tab() { ViewName = "Test1", View = this.container.Resolve<TestView>() });
Tabs.Add(new Tab() { ViewName = "Test2", View = this.container.Resolve<TestView>() });
Tabs.Add(new Tab() { ViewName = "Test3", View = this.container.Resolve<TestView>() });
}
}
public class TestViewModel
{
public ObservableCollection<Test> Tests{ get; set; }
public TestViewModel(ITestDataService testDataService)
{
Tests= new ObservableCollection<Test>(testDataService.GetTests());
}
}
公共类TestViewModel
{
公共可观测集合测试{get;set;}
公共TestViewModel(ITestDataService testDataService)
{
Tests=newobserveCollection(testDataService.GetTests());
}
}
TestView:
<ListView ItemsSource="{Binding Samples}">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding Title}" Margin="8"/>
<TextBlock Text="{Binding Summary}" Margin="8,0,8,8"/>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
对于你提到的问题,你可以考虑两个备选方案:
- 一个简单但不完全优雅的解决方法是重命名测试视图,并创建3个不同的测试视图,其中每个视图都知道视图模型将绑定到其数据上下文
- 但是,另一方面,您可以只保留一个通用的TestView,并从MainViewModel构造函数处理每个实例的DataContext。由于MainViewModel类正在将所有TestView实例添加到TabList中,因此每个TestView实例的DataContext都将在该位置进行设置。MainViewModel将负责创建每个TestView以及视图的相应ViewModel的管理器 因此,您可以解析TestView实例,并在NewTab语句之前使用适当的ViewModel设置其DataContext
public class MainViewModel
{
public List<Tab> Tabs { get; set; }
IUnityContainer container;
public MainViewModel(IUnityContainer container)
{
this.container = container;
TestView view1 = this.container.Resolve<TestView>();
view1.DataContext = this.container.Resolve<Test1ViewModel>();
TestView view2 = this.container.Resolve<TestView>();
view2.DataContext = this.container.Resolve<Test2ViewModel>();
TestView view3 = this.container.Resolve<TestView>();
view3.DataContext = this.container.Resolve<Test3ViewModel>();
Tabs = new List<Tab>();
Tabs.Add(new Tab() { ViewName = "Test1", View = view1 });
Tabs.Add(new Tab() { ViewName = "Test2", View = view2 });
Tabs.Add(new Tab() { ViewName = "Test3", View = view3 });
}
}
public类主视图模型
{
公共列表选项卡{get;set;}
i单元容器;
公共主视图模型(IUnityContainer容器)
{
this.container=容器;
TestView view1=this.container.Resolve();
view1.DataContext=this.container.Resolve();
TestView view2=this.container.Resolve();
view2.DataContext=this.container.Resolve();
TestView view3=this.container.Resolve();
view3.DataContext=this.container.Resolve();
Tabs=新列表();
添加(新选项卡(){ViewName=“Test1”,View=view1});
添加(新选项卡(){ViewName=“Test2”,View=view2});
Tabs.Add(new Tab(){ViewName=“Test3”,View=view3});
}
}
正如您所看到的,概念是MainViewModel创建每个选项卡,每个选项卡都带有问题中描述的TestView,并且它还将管理其DataContext属性的配置。考虑到设置DataContext将是视图创建的一部分,MainViewModel仍将负责完整创建每个TestView及其相应的DataContext
我想澄清,在每个DataContext上设置的ViewModel将是相应的TestViewModel,而不是MainViewModel本身。通过这种方式,MainViewModel将能够使用每个TestView的特定设置解析每个测试实例
尝试使用通用ViewModel,还需要配置每个实例,这将添加比仅设置DataContext更多不干净的代码。根据我的理解,最好用描述性名称而不是一个通用的ViewModel来封装不同ViewModel上的每个测试行为
我希望我已经澄清了建议的方法
问候。我不确定是否100%理解您的问题,但我尝试一下
ObservableCollection<Test1Value> data1 = new ObservableCollection<Test1Value>(new Test1Value[]
{
new Test1Value("Location1", 23.5),
new Test1Value("Location2", 52.5),
new Test1Value("Location3", 85.2)
});
ObservableCollection<Test2Value> data2 = new ObservableCollection<Test2Value>(new Test2Value[]
{
new Machine("Machine1", "OK"),
new Machine("Machine2", "not OK"),
new Machine("Machine3", "OK"),
new Machine("Machine4", "open")
});
CompositeCollection coll = new CompositeCollection();
coll.Add(new CollectionContainer() { Collection = data1 });
coll.Add(new CollectionContainer() { Collection = data2 });
Data = coll;
<ItemsControl ItemsSource="{Binding Data}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.Resources>
<DataTemplate DataType="{x:Type local:Test1Value}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}"/>
<TextBlock Text=" ("/>
<TextBlock Text="{Binding MessuredValue}"/>
<TextBlock Text=")"/>
</StackPanel>
</DataTemplate>
<DataTemplate DataType="{x:Type local:Test2Value}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Machine}"/>
<TextBlock Text=" - "/>
<TextBlock Text="{Binding Status}"/>
</StackPanel>
</DataTemplate>
</ItemsControl.Resources>
</ItemsControl>
ObservableCollection数据1=新的ObservableCollection(新的Test1Value[]
{
新的测试1值(“位置1”,23.5),
新的测试1值(“位置2”,52.5),
新测试1值(“位置3”,85.2)
});
ObservableCollection数据2=新的ObservableCollection(新的Test2Value[]
{
新机器(“机器1”,“正常”),
新机器(“机器2”,“不正常”),
新机器(“机器3”,“正常”),
新机器(“机器4”,“打开”)
});
CompositeCollection coll=新的CompositeCollection();
coll.Add(new CollectionContainer(){Collection=data1});
coll.Add(new CollectionContainer(){Collection=data2});
数据=coll;