如何使用不同的视图模式进行xaml控件 [英] how to make a xaml control with different view modes
问题描述
我正在尝试学习如何将视图与其关联的视图模型分离,同时使视图具有尽可能少的代码隐藏或没有代码隐藏。
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 DataTrigger
s 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 ContentControl
s which use those Style
s, 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屋!