wpf MvvM 命令数据上下文问题
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15526715/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
wpf MvvM Command data-context issue
提问by DMasta
I googled all I could but could not find exactly what I was looking for. I have few issues...
我用谷歌搜索了所有我可以但找不到我正在寻找的东西。我的问题很少...
This is my code structure:
这是我的代码结构:
My Command Class:
我的命令类:
public class BrowseCommand : ICommand
{
//Code here
}
Inside ViewModel:
内部视图模型:
public class ExampleViewModel
{
public ExampleViewModel()
{
BrowseCommand = new BrowseCommand();
}
public ICommand BrowseCommand
{
get;
private set;
}
//More Code...
}
MainWindow.xaml.cs:
主窗口.xaml.cs:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new ExampleViewModel();
}
}
MainWindow.xaml:
主窗口.xaml:
Window x:Class="Ship32RcParser.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525" >
<Grid>
<Button Content="Browse" Command="{Binding BrowseCommand}"/>
<Button Content="Search" Command="{Binding I_NEED_HELP_HERE}" />
</Grid>
</Window>
I understand that my Browse works fine because of MainWindow.xaml.cs has
我知道我的浏览工作正常,因为 MainWindow.xaml.cs 有
DataContext = new ExampleViewModel();
However I do not like that
然而我不喜欢那样
- I do not want to have anything in .cs file
- How do i have more than one datacontext - meaning if I want to have command from different ViewModel classes... I know its possible but its going to be bit ugly...
- 我不想在 .cs 文件中包含任何内容
- 我如何拥有多个数据上下文 - 意思是如果我想从不同的 ViewModel 类中获得命令......我知道它可能但它会有点难看......
When I was searching for solutions I came across dependencies. For example I could do in my xaml file something like this
当我在寻找解决方案时,我遇到了依赖关系。例如我可以在我的 xaml 文件中做这样的事情
xmlns:local="clr-namespace:myMvvMwpfProj.ViewModel"
and then use "local". However, when I tried it did not work as I expected it to work... I also saw something like
然后使用“本地”。然而,当我尝试它并没有像我预期的那样工作时......我也看到了类似的东西
xmlns:local="using:myMvvMwpfProj.Command"
can someone explain those too please. Does "local" give me an access to classes? If I have CommandA, CommandB, CommandC classes. Should I be able to do local:CommandA.ExecuteFoo ?
有人可以解释一下吗?“本地”是否让我可以访问课程?如果我有 CommandA、CommandB、CommandC 类。我应该可以做 local:CommandA.ExecuteFoo 吗?
I guess the big question is how do I reference/access properties from different objects. in Xaml
我想最大的问题是如何从不同的对象引用/访问属性。在 Xml 中
thank you all in advance
谢谢大家
回答by Rachel
The DataContextin WPF is the data layer that sites behind the UI layer. Bindings are used to query properties from the data layer for use in the UI layer.
该DataContext在WPF是数据层的UI层后面的网站。绑定用于从数据层查询属性以在 UI 层中使用。
If your UI layer is going to have two buttons (Browse and Search), then you typically want your data layer to have two commands: BrowseCommandand SearchCommand
如果您的 UI 层将有两个按钮(浏览和搜索),那么您通常希望您的数据层有两个命令:BrowseCommand和SearchCommand
It is possible to write a binding that queries something other than the current DataContextthough. I actually wrote another SO answeryesterday about this, which contains some examples.
可以编写一个绑定来查询当前以外的其他内容DataContext。实际上,我昨天写了另一个关于此的SO答案,其中包含一些示例。
The most common ways are ElementNameor RelativeSource, which will
find another UI element in the VisualTree so you can use it as the binding's source, like this:
最常见的方法是ElementNameor RelativeSource,它将在 VisualTree 中找到另一个 UI 元素,以便您可以将其用作绑定的源,如下所示:
<Button Command="{Binding ElementName=SomeXAMLObjectName,
Path=DataContext.BrowseCommand}" />
<Button Command="{Binding
RelativeSource={RelativeSource AncestorType={x:Type Window}},
Path=DataContext.BrowseCommand}" />
A 3rd option is to create an instance of an object in the <XXXX.Resources>in the XAML, and set the source to that instance using it's x:Key, like this:
第 3 个选项是<XXXX.Resources>在 XAML 中创建对象的实例,并使用它的将源设置为该实例x:Key,如下所示:
<Window.Resources>
<local:MyViewModel x:Key="MyViewModelInstance" />
</Window.Resources>
...
<Button Command="{Binding Source={StaticResource MyViewModelInstance},
Path=BrowseCommand}">
You can also set the binding's Sourceproperty to a static object so you don't need to create an instance of the object in the .Resources, like this:
您还可以将绑定的Source属性设置为静态对象,这样您就不需要在 中创建对象的实例.Resources,如下所示:
<Button Command="{Binding Source={x:Static local:MyStaticClass.BrowseCommand}}">
This only works for static classes though, as it won't actually create a new instance of an object for the binding.
但这仅适用于静态类,因为它实际上不会为绑定创建对象的新实例。
To answer your other question, when you write
回答你的另一个问题,当你写
xmlns:local="clr-namespace:myMvvMwpfProj.ViewModel"
you are telling the XAML to use "local" as a shortcut to "myMvvMwpfProj.ViewModel" (xmlns stands for XML Namespace), so something like local:MyStaticClass.BrowseCommandmeans to bind to myMvvMwpfProj.ViewModel.MyStaticClass.BrowseCommand.
您告诉 XAML 使用“本地”作为“myMvvMwpfProj.ViewModel”(xmlns 代表XML 命名空间)的快捷方式,因此类似于local:MyStaticClass.BrowseCommand绑定到myMvvMwpfProj.ViewModel.MyStaticClass.BrowseCommand.
If you're new to WPF and MVVM, I'd actually recommend checking out a couple blog articles I wrote specifically for new WPF/MVVM users.
如果您不熟悉 WPF 和 MVVM,我实际上建议您查看一些我专门为新 WPF/MVVM 用户编写的博客文章。
They'll help you get a better understanding of how WPF and the MVVM pattern work.
它们将帮助您更好地了解 WPF 和 MVVM 模式的工作原理。
回答by Dave
You can set up the datacontext in your View with <Grid DataContext = "{Binding}">
您可以在您的视图中设置数据上下文 <Grid DataContext = "{Binding}">
You have 1 viewmodel per view but you can have many bound commands! I suggest you look up Josh Smiths RelayCommand as this make this so much easier! A guide is here:
每个视图有 1 个视图模型,但您可以有许多绑定命令!我建议您查找 Josh Smiths RelayCommand,因为这使这变得更加容易!指南在这里:
Create a new class
创建一个新类
class RelayCommand : ICommand
{
private Action<object> _action;
public RelayCommand(Action<object> action)
{
_action = action;
}
#region ICommand Members
public bool CanExecute(object parameter)
{
return true;
}
public event EventHandler CanExecuteChanged;
public void Execute(object parameter)
{
_action(parameter);
}
#endregion
}
And in your ViewModel
在你的 ViewModel
public ICommand BrowseCommand {get; set;}
public ICommand SearchCommand {get; set;}
public ExampleViewModel()
{
this.BrowseCommand = new RelayCommand(new action<object>(MethodNameEnteredHere);
this.SearchCommand = new RelayCommand(new action<object>(OtherMethodNameEnteredHere);
}
So, your xaml would be
所以,你的 xaml 将是
<Grid DataContext = "{Binding}">
<Button Content="Browse" Command="{Binding BrowseCommand}"/>
<Button Content="Search" Command="{Binding SearchCommand}" />
</Grid>
回答by Avram Tudor
If you want your view to use objects from various viewmodels you will have to:
如果您希望您的视图使用来自各种视图模型的对象,您将必须:
Either have some instances in your main ViewModel for the other view models you want to use and thus your binding will be soemthing like {Binding AlternativeViewModelInstance.NewCommand}
Locate the regions in your view that need bindings on a different data context and separate them into different view-viewmodel couples.
要么在您的主 ViewModel 中有一些实例用于您要使用的其他视图模型,因此您的绑定将类似于 {Binding AlternativeViewModelInstance.NewCommand}
定位视图中需要绑定到不同数据上下文的区域,并将它们分成不同的视图-视图模型对。

