动态呈现控件的 MVVM 方式
我需要在不同的进程开始时显示某种动画。我最初的想法是简单地向 XAML 添加一些
标记,并将它们绑定到视图模型对象中的一个属性,然后简单地为该属性分配一个 ProgressBar
,一些繁忙的旋转器或其他什么。
这可行,但我不喜欢它。我不喜欢它的主要原因是视图模型不应该参与表示事务,而这种模式显然打破了这种范式。
这几乎就是我的(丑陋的)代码:
XAML:
<ContentControl Content="{Binding ProcessAAnimation}" />
在视图模型类中:
public object ProcessAAnimation
{
get { return _processAAnimation; }
private set
{
_processAAnimation = value;
OnPropertyChanged("ProcessAAnimation");
}
}
public object IsProcessARunning
{
get { return _processARunning; }
private set
{
if (value == _processARunning)
return;
_processRunnings = value;
if (value)
ProcessAAnimation = SomeNiftyAnimationControl();
else
{
if (ProcessAAnimation is IDisposable)
((IDisposable)ProcessAAnimation).Dispose();
ProcessAAnimation = null;
}
}
}
// (clipped: More properties for "Process B", "Process C" and so on)
那么,是否有更好的模式来实现这一点。最好是一种可以单独使用 XAML 动态创建动画控件的模式?
请注意,我已经测试了一个解决方案,其中声明了三个不同的动画控件,然后将它们的 Visibility
属性绑定到视图模型状态。然而,这在我的书中低于标准,因为我不想只是隐藏控件,我希望它们消失,除非需要。此外,这也使得无法根据需要动态地使用不同类型的动画。
有人吗?
I have a need to display some kind animation as different processes gets started. My initial idea was to simply add some <ContentControl>
tags to the XAML and bind them to a property in the View Model object which then simply assigned this property a ProgressBar
, some busy spinner or whatever.
This works but I don't like it. The primary reason I don't like it is because the View Model should not involve itself in presentation matters and this pattern clearly breaks that paradigm.
This is pretty much what my (ugly) code looks like atm:
XAML:
<ContentControl Content="{Binding ProcessAAnimation}" />
In View Model class:
public object ProcessAAnimation
{
get { return _processAAnimation; }
private set
{
_processAAnimation = value;
OnPropertyChanged("ProcessAAnimation");
}
}
public object IsProcessARunning
{
get { return _processARunning; }
private set
{
if (value == _processARunning)
return;
_processRunnings = value;
if (value)
ProcessAAnimation = SomeNiftyAnimationControl();
else
{
if (ProcessAAnimation is IDisposable)
((IDisposable)ProcessAAnimation).Dispose();
ProcessAAnimation = null;
}
}
}
// (clipped: More properties for "Process B", "Process C" and so on)
So, is there a better pattern to achieve this. Preferrably, a pattern where I can create my animation controls dynamically using XAML alone?
Please note that I have already tested a solution where I declare three different animation controls and then bind their Visibility
property to the View Model state. That, however, is below par in my book because I don't want to just hide the controls, I want them to be gone unless needed. Besides, that would also make it impossible to dynamically use different types of animations for whatever needs may be.
Anyone?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
那么你的 ViewModel 了解操作和进度本身。其余的可以通过触发器来完成。至少我们就是这样做的。所以你的ViewModel有一个属性“IsLoadingImage”,例如,当你的viewmodel启动一个BackgroundWorker来加载大图像时设置它,它还返回BackgroundWorker“ImageLoadingProgress”报告的进度,现在这两个属性足以传递给你的View 。您的视图由进度条或特殊动画的自定义控件组成。您现在可以在触发器中绑定“IsLoadingImage”来切换 ProgressBar/Animation 控件的可见性,并将这些值绑定到“ImageLoadingProgress”。
就像我说的,这就是我们处理它的方式,并且我们的应用程序大量使用了 MVVM。
编辑对评论的响应:如何更改触发器中的模板
这假设
MyType
是一个可以具有ControlTemplate
的控件,并且DataContext
有一个属性IsActive
来切换模板。Well your ViewModel knows about the operation and the progress itself. The rest can be accomplished via Triggers. At least thats the way we do it. So your ViewModel has a property "IsLoadingImage" for example, which is set when your viewmodel starts a BackgroundWorker for loading a big image, it also returns the progress reported by the BackgroundWorker "ImageLoadingProgress" now these two properties are enough to pass to your View. Your view, consists of a Progress bar or a custom control for your special animation. You could now bind the "IsLoadingImage" in a Trigger to toggle the ProgressBar/Animation control visibility and the Value of these is bound to "ImageLoadingProgress".
Like i said, thats how we handle it, and our application makes heavy use of MVVM.
Edit respond to a comment: How to change the template in a trigger
This assumes that
MyType
is a control that can has aControlTemplate
and that theDataContext
has a PropertyIsActive
to toggle the Template.