Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/google-chrome/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Wpf 具有不同viewmodel的相同视图-prism_Wpf_Mvvm_Prism - Fatal编程技术网

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

作为个人观点,第二种方法可能更干净。特别是如果需要第四个测试视图,而不需要创建新的视图类型

更新:

关于在MainViewModel中设置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;