应用 MVVM 模式时遇到问题

发布于 2024-12-01 14:13:39 字数 1947 浏览 0 评论 0原文

我在应用 MVVM 模式时遇到一些麻烦,首先我按照这个示例来学习如何应用和使用该模式...

http://msdn.microsoft.com/en-us/magazine/dd419663.aspx

所以我的问题是在视图与ViewModel ...

在示例中,我们有一个带有 CollectionViewSource 的视图,其中 Source 是 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 AllCustomersViewModel:

public class AllCustomersViewModel : WorkspaceViewModel
{
    (...)

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

    (...)
}

但他使用 ResourceDictionary,在 View 和 ViewModel 之间应用 DataTemplate:

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

但我的问题是因为我没有使用 ResourceDictionary,因此我认为我可以将 DataTemplate 放在窗口的资源中,在那里我将拥有我的视图(对我来说,这是放置 DataTemplate 的更逻辑位置)...但由于某种原因,数据没有出现在 ListView 中,所以我问为什么?

i am having some troubles applying the MVVM pattern, for start i am following this example to learn how to apply and use the pattern...

http://msdn.microsoft.com/en-us/magazine/dd419663.aspx

So my problem is establishing the "connection" between the View with the ViewModel...

In the example we have a View with a CollectionViewSource where the Source is the AllCustomers property:

<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>

who belongs to the ViewModel AllCustomersViewModel:

public class AllCustomersViewModel : WorkspaceViewModel
{
    (...)

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

    (...)
}

but he uses a ResourceDictionary where he applies a DataTemplate between the View and the ViewModel:

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

but my problem is because i am not using a ResourceDictionary, and because of that i thought that i can put the DataTemplate in the Resources of the Window where i will have my View (for me is the more logic place to put the DataTemplate)... But for some reason the Data isn't appearing in the ListView, and so i ask why?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

终弃我 2024-12-08 14:13:39

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

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

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

请参阅这篇文章:

http://www.codeproject .com/KB/WPF/MVVMQuickTutorial.aspx

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

I wouldn't attach the view model in the Xaml. This hard-codes the Xaml to a specific view model.

Instead, I'd override the Application startup:

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

See this article:

http://www.codeproject.com/KB/WPF/MVVMQuickTutorial.aspx

This approach is also helpful if you use some sort of tool to dynamically bind your view models in the future, like MEF, Castle.Windsor or Prism.

雪若未夕 2024-12-08 14:13:39

我从不将视图模型绑定到 XAML 中的视图。我更喜欢自己控制何时设置绑定。我总是在视图上放置一个属性,其中包含对视图模型的引用。这样,我可以根据需要更改视图模型,而不会因 XAML 绑定而产生任何毫无戒心的后果。另外,这样做允许我在视图模型上放置一个 INotify 处理程序,以便在切换视图模型时所有更改都会自动更新。

I never bind my view models to my view in XAML. I prefer to have control over when that binding is set myself. I always put a property on the View that contains the reference to the view Model. That way I can change the view model out if needed without any unsuspecting consequences from XAML binding. Plus doing it this way allows me to put an INotify handler on the view model so all changes are updated automatically when the view model is switched.

无论指定 DataType 的数据用作要显示的内容,不带键的 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>

通常您只使用窗口作为 shell,并且内容是动态设置的。

DataTemplates without key are applied implicitly whereever data of the specified DataType is used as content that is to be displayed. That means that your ViewModel needs to appear somewhere, for example as the content of a ContentControl or an item of an ItemsControl.

So if you have a window you need to have an instance of the ViewModel in it:

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

Normally you only use windows as shells though, and the content is set dynamically.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文