我是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}}}"
这真的有必要吗?
答案 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上设置,它将一直查找树到持有控件的窗口。
如果没有看到你的所有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