Wpf 应用MVVM模式时遇到问题

Wpf 应用MVVM模式时遇到问题,wpf,mvvm,wpf-controls,Wpf,Mvvm,Wpf Controls,我在应用MVVM模式时遇到了一些问题,首先,我将按照这个示例学习如何应用和使用该模式 所以我的问题是在视图和ViewModel之间建立“连接” 在本例中,我们有一个具有CollectionViewSource的视图,其中源是AllCustomers属性: <UserControl x:Class="DemoApp.View.AllCustomersView" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta

我在应用MVVM模式时遇到了一些问题,首先,我将按照这个示例学习如何应用和使用该模式

所以我的问题是在视图和ViewModel之间建立“连接”

在本例中,我们有一个具有CollectionViewSource的视图,其中源是AllCustomers属性:

<UserControl 
  x:Class="DemoApp.View.AllCustomersView"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase">
    <UserControl.Resources>
        <CollectionViewSource x:Key="CustomerGroups" Source="{Binding Path=AllCustomers}"/>
    </UserControl.Resources>

    <DockPanel>
        <ListView AlternationCount="2" DataContext="{StaticResource CustomerGroups}" ItemsSource="{Binding}">
            <ListView.View>
                <GridView>
                    <GridViewColumn Header="Name" DisplayMemberBinding="{Binding Path=DisplayName}"/>
                    <GridViewColumn Header="E-mail" DisplayMemberBinding="{Binding Path=Email}"/>
                </GridView>
            </ListView.View>
        </ListView>            
    </DockPanel>
</UserControl>

谁属于ViewModel AllCustomerViewModel:

public class AllCustomersViewModel : WorkspaceViewModel
{
    (...)

    public ObservableCollection<CustomerViewModel> AllCustomers { get; private set; }

    (...)
}
<DataTemplate DataType="{x:Type vm:AllCustomersViewModel}">
    <vw:AllCustomersView />
</DataTemplate>
公共类AllCustomerViewModel:WorkspaceViewModel
{
(...)
public observeCollection AllCustomers{get;private set;}
(...)
}
但他使用ResourceDictionary,在视图和ViewModel之间应用DataTemplate:

public class AllCustomersViewModel : WorkspaceViewModel
{
    (...)

    public ObservableCollection<CustomerViewModel> AllCustomers { get; private set; }

    (...)
}
<DataTemplate DataType="{x:Type vm:AllCustomersViewModel}">
    <vw:AllCustomersView />
</DataTemplate>


但我的问题是因为我没有使用ResourceDictionary,正因为如此,我认为我可以将DataTemplate放在窗口的Resources中,在那里我可以看到我的视图(对我来说,放置DataTemplate更合乎逻辑)。。。但是由于某些原因,数据没有出现在ListView中,因此我问为什么?

DataTemplates
不带键隐式应用于指定的
数据类型的任何数据用作要显示的内容。这意味着您的ViewModel需要出现在某个地方,例如作为
ContentControl
的内容或
ItemsControl
的项

因此,如果您有一个窗口,则需要在其中包含ViewModel的实例:

<Window ...>
    <Window.Resources>
        <DataTemplate DataType="{x:Type vm:AllCustomersViewModel}">
            <vw:AllCustomersView />
        </DataTemplate>
    </Window.Resources>
    <Window.Content>
        <vm:AllCustomersViewModel />
    </Window.Content>
</Window>


不过,通常您仅将windows用作shell,并且内容是动态设置的。

无键数据模板将隐式应用于指定的
数据类型的任何数据用作要显示的内容。这意味着您的ViewModel需要出现在某个地方,例如作为
ContentControl
的内容或
ItemsControl
的项

因此,如果您有一个窗口,则需要在其中包含ViewModel的实例:

<Window ...>
    <Window.Resources>
        <DataTemplate DataType="{x:Type vm:AllCustomersViewModel}">
            <vw:AllCustomersView />
        </DataTemplate>
    </Window.Resources>
    <Window.Content>
        <vm:AllCustomersViewModel />
    </Window.Content>
</Window>


不过,通常您只将windows用作shell,并且内容是动态设置的。

我不会在Xaml中附加视图模型。这会将Xaml硬编码到特定的视图模型

相反,我会覆盖应用程序启动:

private void OnStartup(object sender, StartupEventArgs e)
{
    Views.MainView view = new Views.MainView();
    view.DataContext = new ViewModels.MainViewModel();
    view.Show();
}
见本文:


如果您将来使用某种工具来动态绑定视图模型,例如MEF、Castle.Windsor或Prism,这种方法也很有用。

我不会在Xaml中附加视图模型。这会将Xaml硬编码到特定的视图模型

相反,我会覆盖应用程序启动:

private void OnStartup(object sender, StartupEventArgs e)
{
    Views.MainView view = new Views.MainView();
    view.DataContext = new ViewModels.MainViewModel();
    view.Show();
}
见本文:


如果您将来使用某种工具来动态绑定视图模型(如MEF、Castle.Windsor或Prism),这种方法也很有用。

我从不在XAML中将视图模型绑定到我的视图。我更喜欢自己控制绑定设置的时间。我总是在视图上放置一个属性,该属性包含对视图模型的引用。这样,如果需要的话,我就可以更改视图模型,而不会因为XAML绑定而产生任何意外的后果。另外,通过这种方式,我可以在视图模型上放置INotify处理程序,以便在切换视图模型时自动更新所有更改

我从不将视图模型绑定到XAML中的视图。我更喜欢自己控制绑定设置的时间。我总是在视图上放置一个属性,该属性包含对视图模型的引用。这样,如果需要的话,我就可以更改视图模型,而不会因为XAML绑定而产生任何意外的后果。另外,通过这种方式,我可以在视图模型上放置INotify处理程序,以便在切换视图模型时自动更新所有更改

但就我现在对模式的理解而言,我们使用视图作为控件,对吗?那么我们还是要实例化ViewModel吗?按照我编写代码的方式,他不会给出任何错误或警告,但他不会访问集合以将数据绑定到ListView。我已经构建了一个非常类似的应用程序,它基于我问题中的示例,但适应了我想要的…@Miguel:你的代码不显示任何列表视图,只显示你如何创建CollectionViewSource,以及你是否创建一个视图,然后创建viewmodel或其他方式取决于你,如果您为viewmodels创建datatemplates,则意味着您首先创建viewmodel。Yes不会显示我正在使用ListView的任何位置,但我已将我的应用程序基于问题中链接的MvvmDemo。所以我在ListView中使用VM,所以我不需要灌输它,对吗?我错过了什么?!我所做的唯一不同于链接示例的事情是我没有使用ResourceDictionary…但就我目前对该模式的理解而言,我们使用视图作为控件,对吗?那么我们还是要实例化ViewModel吗?按照我编写代码的方式,他不会给出任何错误或警告,但他不会访问集合以将数据绑定到ListView。我已经构建了一个非常类似的应用程序,它基于我问题中的示例,但适应了我想要的…@Miguel:你的代码不显示任何列表视图,只显示你如何创建CollectionViewSource,以及你是否创建一个视图,然后创建viewmodel或其他方式取决于你,如果您为viewmodels创建datatemplates,则意味着您首先创建viewmodel。Yes不会显示我正在使用ListView的任何位置,但我已将我的应用程序基于问题中链接的MvvmDemo。所以我在ListView中使用VM,所以我不需要灌输它,对吗?我错过了什么?!与链接示例不同的是,我没有使用ResourceDictionary。。。