MVVM方式使用不同的控件来编辑不同的对象

发布于 2024-10-17 10:26:15 字数 346 浏览 2 评论 0原文

我需要设计一个窗体,左侧有一个树视图,其余区域有一个用于其他控件的容器。每当用户在树视图中选择一个项目时,右侧就会出现一些自定义控件。例如,假设树视图包含值“音频设置”和“视频设置”,并且我有两个可以绑定到这些设置的控件,并且我想在需要时将它们显示在表单上。

现在,根据我所读到的有关 MVVM 的内容,我不应该拥有将返回 UserControls 或 DataTemplates 的属性,对吗?正如我所见,这将与“虚拟机不应该知道视图的实现细节”相混淆。那么,在MVVM方面我该如何正确处理这种情况呢?我应该为此使用转换器吗?如果是的话,它会是什么样子?

我目前无法提供任何代码(主要是因为没有代码),但如果需要,我会尽力澄清问题。 提前致谢。

I need to design a form with a treeview in the left and a container for some other control in the remaining area. Whenever user selects an item in the treeview some custom control appears on the right. For example, let's say that the treeview contains values "Audio settings" and "Video settings", and I have two controls that can be bound to these settings and I want to display them on the form when needed.

Now, from what I've read about MVVM, I shouldn't have properties that will return UserControls or DataTemplates, am I right? It will be messing with "VM shouldn't know implementation details of the view" as I see it. So, how do I handle this situation properly in terms of MVVM? Should I maybe use converters for this and if so, how would it look?

I can't provide any code at the moment (mostly because there isn't any), but I will try to clarify the problem if needed.
Thanks in advance.

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

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

发布评论

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

评论(2

┊风居住的梦幻卍 2024-10-24 10:26:15

这就是 WPF 模板系统可以发挥作用的地方。

主要思想是让 ContentControl 根据 TreeView 中所选的值显示适当的视图。

<Window x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:l="clr-namespace:WpfApplication1"
    Title="MainWindow" Height="350" Width="525">
    <DockPanel>

        <ListBox DockPanel.Dock="Left" ItemsSource="{Binding Editors}" SelectedItem="{Binding SelectedEditor}" />

        <ContentControl Content="{Binding SelectedEditor}">
            <ContentControl.Resources>
                <DataTemplate DataType="{x:Type l:VideoViewModel}">
                    <l:VideoView />
                </DataTemplate>
                <DataTemplate DataType="{x:Type l:AudioViewModel}">
                    <l:AudioView />
                </DataTemplate>
            </ContentControl.Resources>
        </ContentControl>

    </DockPanel>
</Window>

AudioViewVideoViewUserControls

正如您所看到的,ContentControl 的内容绑定到 ViewModel 中的 SelectedEditor 属性,该属性也绑定到 Listbox 的 SelectedItem。

所以主视图的 ViewModel 看起来像这样。

public class MainWindowViewModel : INotifyPropertyChanged
{
    public IEnumerable<object> Editors
    {
        get
        {
            yield return new VideoViewModel();
            yield return new AudioViewModel();
        }
    }

    private object selectedEditor;
    public object SelectedEditor
    {
        get { return selectedEditor; }
        set
        {
            if (selectedEditor == value)
                return;
            selectedEditor = value;
            OnPropertyChanged("SelectedEditor");
        }
    }
}

所以你可以看到主 ViewModel 中没有 GUI 数据。

要处理将 TreeView 连接到 ViewModel 中的 SelectedItem 属性,请参阅数据绑定到 WPF Treeview 中的 SelectedItem

This is where the WPF templating system helps out.

The main idea is to have a ContentControl display the appropriate view depending on the selected value in the TreeView.

<Window x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:l="clr-namespace:WpfApplication1"
    Title="MainWindow" Height="350" Width="525">
    <DockPanel>

        <ListBox DockPanel.Dock="Left" ItemsSource="{Binding Editors}" SelectedItem="{Binding SelectedEditor}" />

        <ContentControl Content="{Binding SelectedEditor}">
            <ContentControl.Resources>
                <DataTemplate DataType="{x:Type l:VideoViewModel}">
                    <l:VideoView />
                </DataTemplate>
                <DataTemplate DataType="{x:Type l:AudioViewModel}">
                    <l:AudioView />
                </DataTemplate>
            </ContentControl.Resources>
        </ContentControl>

    </DockPanel>
</Window>

AudioView and VideoView are UserControls.

As you can see, the ContentControl's content is bound to the SelectedEditor property in the ViewModel, which is also bound to the SelectedItem of the Listbox.

So the ViewModel for the main view looks like this.

public class MainWindowViewModel : INotifyPropertyChanged
{
    public IEnumerable<object> Editors
    {
        get
        {
            yield return new VideoViewModel();
            yield return new AudioViewModel();
        }
    }

    private object selectedEditor;
    public object SelectedEditor
    {
        get { return selectedEditor; }
        set
        {
            if (selectedEditor == value)
                return;
            selectedEditor = value;
            OnPropertyChanged("SelectedEditor");
        }
    }
}

So you can see that the main ViewModel has no GUI data in it.

To handle hooking up a TreeView to a SelectedItem property in a ViewModel see Data binding to SelectedItem in a WPF Treeview

娇纵 2024-10-24 10:26:15

您可以实现它,在 ViewModel 中抛出两个属性:ShowAudioSettings 和 ShowVideoSettings,并将其绑定到控件的可见性上。

另外,您可以使用 VisualStateManager

You can implement it throw two properties: ShowAudioSettings and ShowVideoSettings in ViewModel and bind it on Visibility of your controls.

Also, you can make it with VisualStateManager.

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