C# wpf MvvM命令数据上下文问题

C# wpf MvvM命令数据上下文问题,c#,wpf,mvvm,model-binding,command-pattern,C#,Wpf,Mvvm,Model Binding,Command Pattern,我在谷歌上搜索了所有我能找到的,但找不到确切的我要找的东西。我有一些问题 这是我的代码结构: 我的命令类: public class BrowseCommand : ICommand { //Code here } 内部视图模型: public class ExampleViewModel { public ExampleViewModel() { BrowseCommand = new BrowseCommand(); } pu

我在谷歌上搜索了所有我能找到的,但找不到确切的我要找的东西。我有一些问题

这是我的代码结构:

我的命令类:

 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>
但是我不喜欢这样

  • 我不想在.cs文件中有任何内容
  • 我怎样才能有更多 不止一个datacontext-意味着如果我想从 不同的ViewModel类。。。我知道这是可能的,但它正在进行 有点丑
  • 当我搜索解决方案时,我遇到了依赖项。例如,我可以在我的xaml文件中执行类似的操作

    xmlns:local="clr-namespace:myMvvMwpfProj.ViewModel"
    
    然后使用“本地”。然而,当我尝试时,它并没有像我预期的那样工作。。。 我还看到了类似的东西

    xmlns:local="using:myMvvMwpfProj.Command"
    
    有人能解释一下吗。“本地”是否允许我访问课程?如果我有CommandA,CommandB,CommandC类。我应该能够执行local:CommandA.executefo吗

    我想最大的问题是如何引用/访问不同对象的属性。在Xaml中


    提前感谢大家

    您可以使用

    每个视图有一个viewmodel,但可以有许多绑定命令!我建议你去查查Josh Smith的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
    }
    
    类RelayCommand:ICommand
    {
    私人行动;
    公共关系司令部(行动)
    {
    _行动=行动;
    }
    #区域ICommand成员
    公共布尔CanExecute(对象参数)
    {
    返回true;
    }
    公共事件处理程序CanExecuteChanged;
    public void Execute(对象参数)
    {
    _作用(参数);
    }
    #端区
    }
    
    在您的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);
        }
    
    public ICommand BrowseCommand{get;set;}
    公共ICommand SearchCommand{get;set;}
    公共示例ViewModel()
    {
    this.BrowseCommand=newrelaycommand(新操作(MethodNameEnteredHere);
    this.SearchCommand=new RelayCommand(新操作(此处输入的其他方法名);
    }
    
    那么,您的xaml将是

    <Grid DataContext = "{Binding}">
           <Button  Content="Browse" Command="{Binding BrowseCommand}"/>
           <Button  Content="Search" Command="{Binding SearchCommand}"  />
     </Grid>
    

    如果希望视图使用各种viewmodels中的对象,则必须:

  • 或者在主视图模型中为您要使用的其他视图模型提供一些实例,因此您的绑定将类似于{binding alternativeviewmodelness.NewCommand}

  • 在视图中找到需要在不同数据上下文上绑定的区域,并将它们分离到不同的视图-视图模型对中


  • 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}" />
    
    <Window.Resources>
        <local:MyViewModel x:Key="MyViewModelInstance" />
    </Window.Resources>
    
    ...
    
    <Button Command="{Binding Source={StaticResource MyViewModelInstance}, 
                              Path=BrowseCommand}">
    
    <Button Command="{Binding Source={x:Static local:MyStaticClass.BrowseCommand}}">
    
    您还可以将绑定的
    Source
    属性设置为静态对象,这样就不需要在
    .Resources
    中创建对象的实例,如下所示:

    <Button Command="{Binding ElementName=SomeXAMLObjectName, 
                              Path=DataContext.BrowseCommand}" />
    
    <Button Command="{Binding 
                RelativeSource={RelativeSource AncestorType={x:Type Window}}, 
                Path=DataContext.BrowseCommand}" />
    
    <Window.Resources>
        <local:MyViewModel x:Key="MyViewModelInstance" />
    </Window.Resources>
    
    ...
    
    <Button Command="{Binding Source={StaticResource MyViewModelInstance}, 
                              Path=BrowseCommand}">
    
    <Button Command="{Binding Source={x:Static local:MyStaticClass.BrowseCommand}}">
    
    您告诉XAML使用“local”作为“myMvvMwpfProj.ViewModel”(xmlns代表)的快捷方式,因此类似于
    local:MyStaticClass.BrowseCommand
    的内容意味着绑定到
    myMvvMwpfProj.ViewModel.MyStaticClass.BrowseCommand

    如果你是WPF和MVVM的新手,我建议你看看我专门为新WPF/MVVM用户写的几篇博客文章


    它们将帮助您更好地理解WPF和MVVM模式是如何工作的。

    嗨,Rachel,我只是想知道,您现在还在属性更改通知调用中使用字符串还是使用表达式树?@Charleh不,我通常使用Microsoft PRISM的
    NotificationObject
    作为所有对象的基类,这些对象应该是ise
    PropertyChanged
    notifications,它允许我使用实际属性而不是字符串发出更改通知。它使重构更加容易,并消除了属性名称中键入错误的可能性。
    RaisePropertyChanged(()=>this.SomeProperty)
    啊,是的,只是想知道-基于表达式的属性更适合重构,我确实在文章中提到了通知对象,但我没有使用PRISM(我目前使用的是Caliburn.Micro,它使用表达式具有类似的属性通知机制)感谢您的指点。我将查看您的链接,顺便说一句,我还没有看到“一个控件的多个dataContext-MVVM”问题。再次感谢。作为补充说明,默认情况下,
    dataContext
    是从父对象继承的,因此
    dataContext=“{Binding}”
    只是XAML中无用的额外代码。