如何将命令绑定到按钮

时间:2014-06-26 14:19:49

标签: c# wpf xaml

我是wpf和这个花哨的绑定内容的新手,跟着这些tutorial得到了这个XAML

<Button
    x:Name="btn"
    Content="refresh"
    Command="{Binding RefreshCmd}" />

和这段代码:

public someClass ()
{
    InitializeComponent();

    CreateRefreshCmd();
    btn.DataContext=this; // without this line it will not work !!
}

public ICommand RefreshCmd
{
    get;
     internal set;
}

private bool CanExecuteRefreshCmd ()
{
    return true;
}

private void CreateRefreshCmd ()
{
    RefreshCmd=new RelayCommand(e => RefreshExec(), c => this.CanExecuteRefreshCmd());
}

public void RefreshExec ()
{
    // do something fancy here !
}

但没有构造函数中的最后一行它将无效。

在本教程中,这一行不存在。

我该如何避免这种情况?

编辑:

我用visual studio点击数据绑定并得到了这个:

Command="{Binding RefreshCmd, Mode=OneWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type my:spielerei}}}"

这真的有必要吗?

5 个答案:

答案 0 :(得分:4)

要使绑定工作,您需要设置绑定到目标的数据上下文,所以是的,这是必要的。在您在编辑中发布的Command绑定中,指示绑定在类型RefreshCmd的{​​{1}}控件的祖先上查找Button属性,我假设是包含窗口类型。这就是为什么my:spielerei的显式设置不会出现在教程中。

绑定和命令可以在代码隐藏中使用,但更常用于MVVM模式中的视图模型。这涉及将类的DataContext设置为视图模型,其中包含要绑定到的属性和命令。要更改代码以遵循MVVM,我们需要一个视图模型:

DataContext

然后,在代码隐藏中,创建视图模型,并将其指定为对象的数据上下文:

public class SomeClassViewModel
{
    public SomeClassViewModel()
    {
        this.RefreshCmd = new RelayCommand(e => RefreshExec(), c => this.CanExecuteRefreshCmd());
    }

    public ICommand RefreshCmd { get; internal set; }

    private bool CanExecuteRefreshCmd()
    {
        return true;
    }

    public void RefreshExec()
    {
        // do something fancy here !
    }
}

请注意,public class SomeClass { public SomeClass() { InitializeComponent(); this.DataContext = new SomeClassViewModel(); } } 代码隐藏文件中的所有代码都已移至视图模型 - 它现在可以测试,并且您的XAML控件可以通过绑定到属性并执行来与视图模型通信命令。

答案 1 :(得分:0)

如果有绑定对象,绑定将正常工作。此对象从 DataContext 属性中读取。如果未设置此属性,则无法绑定任何内容。这就是为什么需要以下行:

btn.DataContext=this;

您提到的教程以稍微不同的方式进行,即它在XAML中设置 DataContext 。请查看本教程中的 MainWindow.xaml 文件。它在开头包含以下代码,用于填充 DataContext 属性:

<Window x:Class="MvvmCommand.MainWindow" DataContext="{Binding Main, Source={StaticResource Locator}}">

答案 2 :(得分:0)

在WPF中使用Binding时,默认情况下,它会将绑定设置为具有绑定属性的对象的DataContext上的命名属性。所以在你的例子中,按钮的DataContext。 这个属性是通过树继承的,所以如果没有在Button上设置,它将一直查找树到持有控件的窗口。

MSDN on binding

如果没有看到你的所有XAML,我必须猜测,但我猜你还没有设置托管按钮的窗口的datacontext。通过在构造函数中将其显式设置为this,您将绑定源设置为具有该属性的对象,因此它的工作原理。

执行此操作的常规方法是将数据上下文设置为包含该命令的类。通常的设计模式是MVVM。绑定的想法是分离 - 它不像在后面的代码中处理它们的事件,而是它允许您创建一个视图模型或类似的类,它公开命令并将其绑定到视图。这允许您通过视图模型执行单元测试功能,而无需对视图进行单元测试,将视图模型共享到多个视图等。

答案 3 :(得分:0)

需要设置数据上下文,以便绑定框架可以解析值

您可能有各种设置相同的方法

你用过的第一种方法

另一种方法是通过xaml

设置
<Window x:Class="Project.MainWindow"
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     DataContext="{Binding RelativeSource={RelativeSource Self}}">

这里的想法是将数据上下文设置为self。

答案 4 :(得分:0)

简而言之,没有必要。不要将datacontext设置为按钮,在XAML中为页面(视图)设置数据上下文(viemodel)。当然,您的命令必须通过该视图模型公开。

关于另一个问题,我提出了显示命令绑定和跨视图模型通信的简单示例,请在此处查看https://github.com/mikkoviitala/cross-viewmodel-communication