wpf MvvM命令数据上下文问题
本文关键字:上下文 问题 数据 命令 MvvM wpf | 更新日期: 2023-09-27 18:05:09
我用谷歌搜索了所有我能搜索到的东西,但没有找到我要找的东西。我没有什么问题……
这是我的代码结构:
My Command Class:
public class BrowseCommand : ICommand
{
//Code here
}
内部视图模型:
public class ExampleViewModel
{
public ExampleViewModel()
{
BrowseCommand = new BrowseCommand();
}
public ICommand BrowseCommand
{
get;
private set;
}
//More Code...
}
MainWindow.xaml.cs:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new ExampleViewModel();
}
}
MainWindow.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>
我知道我的浏览工作正常,因为MainWindow.xaml.cs有
DataContext = new ExampleViewModel();
但是我不喜欢。
- 我不想在。cs文件中有任何东西
- 我怎么有更多多于一个数据上下文-意思是如果我想从不同的ViewModel类…我知道这是可能的,但它正在发生有点丑…
当我在寻找解决方案时,我遇到了依赖关系。例如,我可以在xaml文件中这样写
xmlns:local="clr-namespace:myMvvMwpfProj.ViewModel"
,然后使用"local"。然而,当我尝试它没有工作,因为我期望它的工作…我还看到了像
这样的东西xmlns:local="using:myMvvMwpfProj.Command"
谁也能解释一下这些。"本地"是否允许我访问课程?如果我有commandda, commanddb, CommandC类。我能做本地命令吗?ExecuteFoo ?
我想最大的问题是我如何从不同的对象引用/访问属性。在Xaml
提前感谢大家
WPF中的DataContext
是位于UI层后面的数据层。绑定用于从数据层查询属性以供UI层使用。
如果你的UI层将有两个按钮(浏览和搜索),那么你通常希望你的数据层有两个命令:BrowseCommand
和SearchCommand
可以编写一个绑定来查询当前DataContext
以外的东西。关于这个问题,我昨天写了另一个答案,里面有一些例子。
最常见的方法是ElementName
或RelativeSource
,这将在VisualTree中找到另一个UI元素,这样就可以将其用作绑定的源,如下所示:
<Button Command="{Binding ElementName=SomeXAMLObjectName,
Path=DataContext.BrowseCommand}" />
<Button Command="{Binding
RelativeSource={RelativeSource AncestorType={x:Type Window}},
Path=DataContext.BrowseCommand}" />
第三种选择是在XAML的<XXXX.Resources>
中创建对象的实例,并使用x:Key
将源设置为该实例,如下所示:
<Window.Resources>
<local:MyViewModel x:Key="MyViewModelInstance" />
</Window.Resources>
...
<Button Command="{Binding Source={StaticResource MyViewModelInstance},
Path=BrowseCommand}">
您还可以将绑定的Source
属性设置为静态对象,这样您就不需要在.Resources
中创建该对象的实例,如下所示:
<Button Command="{Binding Source={x:Static local:MyStaticClass.BrowseCommand}}">
这只适用于静态类,因为它实际上不会为绑定创建对象的新实例。
回答你的另一个问题,当你写
xmlns:local="clr-namespace:myMvvMwpfProj.ViewModel"
你告诉XAML使用"local"作为"myMvvMwpfProj "的快捷方式。ViewModel"(xmlns代表XML名称空间),所以像local:MyStaticClass.BrowseCommand
这样的东西意味着绑定到myMvvMwpfProj.ViewModel.MyStaticClass.BrowseCommand
。
如果你是WPF和MVVM的新手,我建议你看看我专门为WPF/MVVM新用户写的几篇博客文章。
- 你所说的"DataContext"是什么?
- 一个简单的MVVM示例
它们将帮助您更好地理解WPF和MVVM模式是如何工作的。
您可以使用<Grid DataContext = "{Binding}">
在View中设置数据上下文
你有一个视图模型,但你可以有许多绑定命令!我建议你查一下Josh Smiths RelayCommand,因为这会让这变得更容易!指南在这里:
创建一个新类
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
}
在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);
}
那么你的xaml就是
<Grid DataContext = "{Binding}">
<Button Content="Browse" Command="{Binding BrowseCommand}"/>
<Button Content="Search" Command="{Binding SearchCommand}" />
</Grid>
如果你想让你的视图使用来自不同视图模型的对象,你必须:
-
要么有一些实例在你的主ViewModel为其他视图模型你想使用,因此你的绑定将是{binding AlternativeViewModelInstance。NewCommand}
-
找到视图中需要绑定到不同数据上下文的区域,并将它们分离到不同的视图-视图模型对中。