将 [VisualStateManager] 视图状态绑定到 MVVM 视图模型?
如何将控件的 VisualStateManager 状态绑定到视图模型中的属性? 能做到吗?
How do you bind the VisualStateManager state of a control to a property in you viewmodel?
Can it be done?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
其实你可以。
诀窍是创建一个附加属性并添加一个实际调用
GoToState
的属性更改回调:然后您可以在xaml中设置此属性并将绑定添加到您的视图模型,例如任何其他:
Name
和State
是视图模型中的常规属性。当在视图模型中设置Name
时,无论是通过绑定还是其他方式,它都可以更改State
,从而更新视觉状态。State
也可以由任何其他因素设置,但它仍然会更新文本框上的视图状态。由于我们使用普通绑定来绑定到 Status,因此我们可以应用转换器或我们通常能够执行的任何其他操作,因此视图模型不必知道它实际上设置了一个视觉状态名称 State可以是布尔值或枚举或其他任何值。
您还可以在 .net 3.5 上使用 wpftoolkit 使用此方法,但必须将
target
转换为Control
而不是FrameworkElement
。关于视觉状态的另一个快速说明,请确保您不要命名视觉状态,以免它们与内置的视觉状态发生冲突,除非您知道自己在做什么。对于验证来说尤其如此,因为验证引擎将每次更新绑定时尝试设置其状态(在其他一些时间也是如此)。 转到此处获取有关视觉状态名称的参考不同的控制。
Actually you can.
The trick is to make an Attached property and add a property changed callback that actually calls
GoToState
:You can then set this property in you xaml and add a binding to your viewmodel like any other:
Name
andState
are regular properties in the viewmodel. WhenName
is set in the viewmodel, either by the binding or something else, it can change theState
witch will update the visual state.State
could also be set by any other factor and still it would update the view state on the textbox.Since we're using a normal binding to bind to Status, we can apply converters or anything else that we'd normally be able to do, so the viewmodel doesn't have to be aware that its actually setting a visual state name, State could be a bool or an enum or whatever.
You can also use this approach using the wpftoolkit on .net 3.5, but you have to cast
target
to aControl
instead of aFrameworkElement
.Another quick note on visual states, make sure you don't name your visual states so that they conflict with the built in ones unless you know what you're doing. This is especially true for validation since the validation engine will try and set its states everytime the binding is updated (and at some other times as well). Go here for a reference on visual state names for diffrent controls.
我是 WPF 新手,但在以奇怪的方式通过 MVVM 层扭曲状态一段时间后,我终于找到了一个令我满意的解决方案。更改状态作为 ViewModel 逻辑的一部分,并在 XAML 视图中侦听它。不需要转换器或“桥接”方法背后的代码等。
构造函数后面的视图代码
XAML命名空间
XAML绑定
ViewModel代码
现在设置ExampleViewModel的State属性将触发相应的状态观点的改变。确保视觉状态的名称与 State 属性值相对应,或者使用枚举、转换器等使其复杂化。
I'm new to WPF, but after twisting states through MVVM layers in odd ways for some time I finally found a solution I'm happy with. Change the state as part of the ViewModel logic and listen to it in the XAML View. No need for converters or code behind "bridging" methods or the likes.
View Code behind constructor
XAML Namespaces
XAML Bindings
ViewModel Code
Now setting the State property of ExampleViewModel will trigger a corresponding state change in the view. Make sure the visual states have names corresponding to the State property values or complicate it with enums, converters, etc.
阅读这篇文章:Silverlight 4:使用 VisualStateManager 通过 MVVM 实现状态动画
或者,如果您刚刚在两种状态之间切换,则可以使用 DataStateBehaviour。我用它来在显示登录页面时切换背景。
命名空间
XAML
通过使用诸如 Caliburn 这样的框架,这变得更加简单.微。
Have a read of this article: Silverlight 4: using the VisualStateManager for state animations with MVVM
Alternatively, if you're just after switching between two states you can use DataStateBehaviour. I've used this to switch the background when the login page is displayed.
Namespaces
XAML
This is made even simpler by using a framework such as Caliburn.Micro.
下面是我在 WPF 中用于
VisualStateManager
状态的 MVVM 支持的类:在您的 XAML 中:
Here's a class I use for MVVM support of
VisualStateManager
states in WPF:In your XAML:
下面是一个适用于 .NET 4.7.2 的帮助程序类。
显然,微软在某个时候中断了对静态类中自定义附加属性的支持。其他答案会导致 XAML 编译器错误,无法在命名空间中找到内容。
用法示例:
local:VisualStateHelper.visualState="{Binding VisualState}"
Here's a helper class that works with .NET 4.7.2.
Apparently at some point Microsoft broke support for custom attached properties in static classes. The other answers result in XAML compiler errors about not being able to find stuff in the namespace.
Usage example:
local:VisualStateHelper.visualState="{Binding visualState}"