在 XAML 中,我有一个 x:Name 为MyTextBox.
<TextBox x:Name="MyTextBox">Some text</TextBox>
Run Code Online (Sandbox Code Playgroud)
出于速度原因,我想调用该方法.AppendText,例如在后面的 C# 代码中,我会调用MyTextBox.AppendText("...")
然而,这不是很像 MVVM。如果我想使用绑定到我的 ViewModel 来调用控件上的函数,那么实现此目的的优雅方法是什么?
我正在使用 MVVM Light。
如果我想要一个简单、快速的解决方案,我会使用@XAML Lover 的答案。这个答案使用了一种较少 C# 编码的混合行为。
如果我想编写一个可重用的依赖属性,我将使用 @Chris Eelmaa 的答案,我可以将其应用于将来的任何 TextBox。这个例子基于一个依赖属性,虽然稍微复杂一些,但是一旦编写就非常强大和可重用。当它插入本机类型时,使用它的 XAML 也略少。
基本上,当您从控件调用方法时,很明显您正在执行一些与 UI 相关的逻辑。这不应该放在 ViewModel 中。但在某些特殊情况下,我建议创建一个行为。创建一个行为并定义一个Action<string>类型的 DependencyProperty,因为 AppendText 应该将字符串作为参数。
public class AppendTextBehavior : Behavior<TextBlock>
{
public Action<string> AppendTextAction
{
get { return (Action<string>)GetValue(AppendTextActionProperty); }
set { SetValue(AppendTextActionProperty, value); }
}
// Using a DependencyProperty as the backing store for AppendTextAction. This enables animation, styling, binding, etc...
public static readonly DependencyProperty AppendTextActionProperty =
DependencyProperty.Register("AppendTextAction", typeof(Action<string>), typeof(AppendTextBehavior), new PropertyMetadata(null));
protected override void OnAttached()
{
SetCurrentValue(AppendTextActionProperty, (Action<string>)AssociatedObject.AppendText);
base.OnAttached();
}
}
Run Code Online (Sandbox Code Playgroud)
在 OnAttached 方法中,我将在 TextBlock 上创建的扩展方法分配给了 Behavior 的 DP。现在我们可以将此行为附加到 View 中的 TextBlock。
<TextBlock Text="Original String"
VerticalAlignment="Top">
<i:Interaction.Behaviors>
<wpfApplication1:AppendTextBehavior AppendTextAction="{Binding AppendTextAction, Mode=OneWayToSource}" />
</i:Interaction.Behaviors>
</TextBlock>
Run Code Online (Sandbox Code Playgroud)
考虑我们在 ViewModel 中有一个具有相同签名的属性。该属性是此绑定的来源。然后我们可以随时调用该 Action,它会自动调用我们在 TextBlock 上的扩展方法。在这里,我通过单击按钮调用该方法。请记住,在这种情况下,我们的 Behavior 就像 View 和 ViewModel 之间的适配器。
public class ViewModel
{
public Action<string> AppendTextAction { get; set; }
public ICommand ClickCommand { get; set; }
public ViewModel()
{
ClickCommand = new DelegateCommand(OnClick);
}
private void OnClick()
{
AppendTextAction.Invoke(" test");
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2837 次 |
| 最近记录: |