如何使用不同的视图模式进行xaml控件 [英] how to make a xaml control with different view modes

查看:66
本文介绍了如何使用不同的视图模式进行xaml控件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试学习如何将视图与其关联的视图模型分离,同时使视图具有尽可能少的代码隐藏或没有代码隐藏。

I'm trying to learn how to separate a view from its associated viewmodel, while making the view have as little or no code-behind as possible.

my当对象处于显示模式时,该控件具有一个文本块,而当用户想要编辑该字段时,该控件具有一个文本框。在这两种情况下,这些控件都必须绑定到模型视图中的同一字符串,但是仅应根据视图模型的状态显示适当的字符串。以前,我只是将面板子代修改为后面的代码中的新元素...但是据我了解,我应该尝试对视图进行XAML的所有更改。

my control has a textblock when the object is in a display mode, and a textbox when the user wants to edit that field. In both cases, these controls must bind to the same string in the modelview, but only the appropriate one should be displayed depending on the state of the viewmodel. Previously, I'd just modify the panels child to a new element in the codebehind... but as I understand it, I should be trying to make all my changes in XAML for the view.

我的视图模型有一个布尔值,表示它处于显示还是编辑模式。有没有办法根据该布尔值指定使用不同的模板,但是将其全部保留在XAML中?

My viewmodel has a bool denoting if its in display or edit mode. Is there a way to specify use of a different template depending on the value of that bool, but keep it all in XAML?

推荐答案

可以使用DataTriggers来完成您正在说的事情。

There is a way to do what you say you're working on, by using DataTriggers.

首先,定义 Style ,其中包含 DataTrigger 您要使用的。例如,在这里请注意 ContentControl 的两种相同样式,每种样式均具有 DataTrigger 对,它们的样式与其他样式相反:

First, define a Style which contains the DataTriggers you want to use. For example, note here two identical styles for a ContentControl, each with a DataTrigger pair that performs the opposite of the other:

<Window.Resources>
     <Style TargetType="{x:Type ContentControl}" x:Key="HiddenWhenFalse" >
        <Setter Property="Visibility" Value="Collapsed"/>
        <Style.Triggers>
            <DataTrigger  Value="False" Binding="{Binding MyBooleanValue}">
                <Setter Property="Visibility" Value="Collapsed" />
            </DataTrigger>
            <DataTrigger  Value="True" Binding="{Binding MyBooleanValue}">
                <Setter Property="Visibility" Value="Visible" />
            </DataTrigger>
        </Style.Triggers>
    </Style>


    <Style TargetType="{x:Type ContentControl}" x:Key="HiddenWhenTrue" >
        <Setter Property="Visibility" Value="Visible"/>
        <Style.Triggers>
            <DataTrigger  Value="True" Binding="{Binding MyBooleanValue}">
                <Setter Property="Visibility" Value="Collapsed" />
            </DataTrigger>
            <DataTrigger  Value="False" Binding="{Binding MyBooleanValue}">
                <Setter Property="Visibility" Value="Visible" />
            </DataTrigger>
        </Style.Triggers>
    </Style>
</Window.Resources>

然后,在主可视树中定义 ContentControl 使用那些 Style 并分配 Window <的 DataContext / code>或 UserControl 或其他任何ViewModel。这样的事情:

Then, in your main visual tree you would define ContentControls which use those Styles, and assign the DataContext of the Window or UserControl or whatever to your ViewModel. Something like this:

<Grid>
    <StackPanel >
        <Button Content="False" Name="Button2"></Button>
        <Button Content="True" Name="Button1"></Button>
        <ContentControl Style="{StaticResource HiddenWhenFalse}">
            <ContentControl.Content>
                <TextBlock Text="ITS ALL TRUE"/>
            </ContentControl.Content>
        </ContentControl>
        <ContentControl Style="{StaticResource HiddenWhenTrue}">
            <ContentControl.Content>
                <TextBlock Text="ITS ALL FALSE"/>
            </ContentControl.Content>
        </ContentControl>
    </StackPanel>
</Grid>

这里是我正在使用的ViewModel,请注意INotifyPropertyChanged的实现:

Here is the ViewModel I'm using, note the implementation of INotifyPropertyChanged:

Imports System.ComponentModel

Public Class MainWindowViewModel
    Implements INotifyPropertyChanged
    Private _MyBooleanValue = False
    Public Property MyBooleanValue
        Get
            Return _MyBooleanValue
        End Get
        Set(ByVal value)
            _MyBooleanValue = value
            RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(Nothing))
        End Set
    End Property

    Public Event PropertyChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged
End Class

现在,对于本示例而言,我只需将两个按钮连接起来即可设置ViewModel值。如果您想使用命令来连接按钮,则完全不同。值得讨论,但是为了简单起见:

Now, for the purposes of this sample, I simply wired up the two buttons to set the ViewModel value. If you want to use Commanding to wire up buttons, that's an entirely different topic. It's worth discussing, but for the sake of simplicity:

Class MainWindow 
    Private vm As New MainWindowViewModel
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles Button1.Click
        vm.MyBooleanValue = True
    End Sub

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles Button2.Click
        vm.MyBooleanValue = False
    End Sub

    Private Sub MainWindow_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded
        Me.DataContext = vm
    End Sub
End Class

请记住,此示例显式设置了 ContentControl 的样式,并且您必须更改TargetType如果您使用的不是该类的派生类型,则表示您的样式。

Bear in mind that this sample explicitly styles a ContentControl, and that you'll have to change the TargetType of your style if you're working with a type that isn't descended from that class.

这篇关于如何使用不同的视图模式进行xaml控件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆