c# - MVVM:如何对控件进行函数调用?

标签 c# wpf mvvm

在 XAML 中,我有一个 x:Name 为 MyTextBox 的 TextBox。

<TextBox x:Name="MyTextBox">Some text</TextBox>

出于速度原因,我想调用方法 .AppendText,例如在后面的 C# 代码中,我会调用 MyTextBox.AppendText("...")

但是,这不是很像 MVVM。如果我想使用绑定(bind)到我的 ViewModel 来调用控件上的函数,实现此目的的优雅方法是什么?

我正在使用 MVVM Light。

更新

如果我想要一个简单、快速的解决方案,我会使用@XAML Lover 的答案。此答案使用较少 C# 编码的混合行为。

如果我想编写一个可重复使用的依赖属性,我可以在将来将其应用于任何 TextBox,我会使用@Chris Eelmaa 的答案。这个例子是基于一个依赖属性,虽然稍微复杂一点,但是非常强大并且一旦编写就可以重用。由于它插入 native 类型,因此使用它的 XAML 也略有减少。

最佳答案

基本上,当您从控件调用方法时,很明显您正在执行一些与 UI 相关的逻辑。那不应该放在 ViewModel 中。但在某些特殊情况下,我会建议创建一个行为。创建一个 Behavior 并定义一个类型为 Action 的 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();
    }
}

在 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>

假设我们在 ViewModel 中有一个具有相同签名的属性。该属性是此绑定(bind)的来源。然后我们可以随时调用该 Action,这将自动调用我们在 TextBlock 上的扩展方法。在这里,我在单击按钮时调用该方法。请记住,在这种情况下,我们的行为就像 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");
    }
}

关于c# - MVVM:如何对控件进行函数调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27892981/

相关文章:

c# - WPF 还是 GTK?哪一个更好

c# - 在内存中呈现 WPF 用户控件,而不是在屏幕上

c# - 如何查找 RibbonComboBox 的子元素

c# - 从 GroupDescription 获取组

c# - 用户控件不呈现

wpf - 将 MVVM 用于 WPF 对话框

c# - 在 DataTemplate 中声明的 View 在从 Tab 更改为 Tab 时继续创建

c# - 修改数据库C#中的数据

c# - 读取文件长度的最快方法 C#

c# - 添加线程名称