Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/272.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# MVVM WPF中的ICommand_C#_Wpf_Mvvm - Fatal编程技术网

C# MVVM WPF中的ICommand

C# MVVM WPF中的ICommand,c#,wpf,mvvm,C#,Wpf,Mvvm,我正在看这个MVVM的东西,我面临一个问题 情况很简单 我的index.xaml页面中有以下代码 <Grid> <ItemsControl ItemsSource="{Binding}"> <ItemsControl.ItemTemplate> <DataTemplate> <view:MovieView ></view:MovieView&g

我正在看这个MVVM的东西,我面临一个问题

情况很简单

我的index.xaml页面中有以下代码

    <Grid>
    <ItemsControl ItemsSource="{Binding}">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <view:MovieView ></view:MovieView>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</Grid>

在我的index.xaml.cs中

初始化组件(); base.DataContext=新的MovieViewModel(ent.Movies.ToList());

这是我的MoveViewModel

    public class MovieViewModel
{
    readonly List<Movies> _m;
    public ICommand TestCommand { get; set; }
    public MovieViewModel(List<Movies> m)
    {
        this.TestCommand = new TestCommand(this);
        _m = m;
    }
    public List<Movies> lm
    {
        get
        {
            return _m;
        }
    }
}
公共类电影视图模型
{
只读列表;
公共ICommand TestCommand{get;set;}
公共电影视图模型(列表m)
{
this.TestCommand=新的TestCommand(this);
_m=m;
}
公共列表lm
{
得到
{
返回m;
}
}
}
最后

这是我的控件xaml MovieView

    <Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto"></ColumnDefinition>
        <ColumnDefinition Width="Auto"></ColumnDefinition>
    </Grid.ColumnDefinitions>
    <Label VerticalAlignment="Center" Grid.Row="0" Grid.Column="0">Title :</Label><TextBlock VerticalAlignment="Center" Grid.Row="0" Grid.Column="1" Text="{Binding Title}"></TextBlock>  
    <Label VerticalAlignment="Center" Grid.Row="1" Grid.Column="0">Director :</Label><TextBlock VerticalAlignment="Center" Grid.Row="1" Grid.Column="1" Text="{Binding Director}"></TextBlock>
    <Button Grid.Row="2" Height="20" Command="{Binding Path=TestCommand}" Content="Edit" Margin="0,4,5,4" VerticalAlignment="Stretch" FontSize="10"/>
</Grid>

标题:
主任:
所以我的问题是,如果我将ItemsSource设置为Binding

这没有任何意义

如果我设置ItemsSource=“{Binding lm}”

它填充我的itemsControl,但命令(Command=“{Binding Path=TestCommand}”)不起作用

当然,它不起作用,因为TestCommand不属于我的实体对象

所以最后我的问题是

我需要传递什么到ItemsControl才能使其工作


Thx提前

尝试实现INotifyPropertyChanged接口:

public class MovieViewModel : INotifyPropertyChanged
{
    readonly List<Movies> _m;
    private ICommand _testCommand = null;
    public ICommand TestCommand { get { return _testCommand; } set { _testCommand = value; NotifyPropertyChanged("TestCommand"); } }
    public MovieViewModel(List<Movies> m)
    {
        this.TestCommand = new TestCommand(this);
        _m = m;        
    }
    public List<Movies> lm
    {
        get
        {
            return _m;
        }
    }


    public event PropertyChangedEventHandler PropertyChanged;

    protected void NotifyPropertyChanged(string sProp)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(sProp));
        }
    }    
}
公共类电影视图模型:INotifyPropertyChanged
{
只读列表;
私有ICommand_testCommand=null;
public ICommand TestCommand{get{return}TestCommand;}set{{TestCommand=value;NotifyPropertyChanged(“TestCommand”);}
公共电影视图模型(列表m)
{
this.TestCommand=新的TestCommand(this);
_m=m;
}
公共列表lm
{
得到
{
返回m;
}
}
公共事件属性更改事件处理程序属性更改;
受保护的void NotifyPropertyChanged(字符串存储过程)
{
if(PropertyChanged!=null)
{
PropertyChanged(此,新PropertyChangedEventArgs(sProp));
}
}    
}
发生的情况是TestCommand有一个值,UI没有收到正在发生更改的通知。。在使用依赖项属性解决此问题的控件上,在数据对象上,可以使用INotifyPropertyChanged接口

其次,电影对象没有对父对象的引用

您可以通过三种不同的方式解决此问题:

  • 将引用返回到电影上的模型,并将绑定路径设置为:ie。。如果您的属性名为ParentMovieModel,则绑定如下:

    {Binding Path=ParentMovieModel.TestCommand}

  • 基于ElementName进行绑定,如下所示:查找设置DataContext的父控件,并为其命名:即Root。现在基于ElementName创建一个绑定,如下所示:

    {Binding ElementName=Root,Path=DataContext.TextCommand}

  • 基于相对资源进行绑定,如下所示:按类型查找父控件,并使用与上面相同的路径

    {Binding RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type yourparentwindowtype},Path=DataContext.TextCommand}

  • 在ItemsSource=“{Binding Path=lm}>的情况下,

    怎么样

    itemsControl运行良好,但我完全绕过了我的MovieViewModel

    我在输出窗口中得到了这个

    System.Windows.Data错误:39:BindingExpression路径错误:在“对象”“电影”(HashCode=1031007)“上找不到“TestCommand”属性。BindingExpression:Path=TestCommand;DataItem='Movies'(HashCode=1031007);目标元素是“按钮”(名称=“”);目标属性为“Command”(类型为“ICommand”)

    电影是我的实体对象,只拥有标题和导演属性

    事情是这样的

     <ItemsControl DataContext="{Binding}" ItemsSource="{Binding lm}">
    
     Command="{Binding Path=DataContext.TestCommand, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" 
    
    
    Command=“{Binding Path=DataContext.TestCommand,RelativeSource={RelativeSource-AncestorType={x:Type-ItemsControl}}”
    
    所以相对资源是我错过的东西


    如果有人对此有一个很好的解释,我肯定会很高兴。

    一旦您的项目被呈现,每个项目都会被设置为它所代表的特定行的DataContext,因此您不再能够引用您的第一个DataContext。。此外,由于您位于DataTemplate中,因此当需要该模板时,绑定将开始工作。。因此,在这种情况下,您需要通过RelativeSource绑定查找父控件

    希望这能解释一些事情。

    //包括名称空间
    
    //include namespace
    using Microsoft.Practices.Composite.Wpf.Commands;
    
    readonly List<Movies> _m;
        public ICommand TestCommand { get; set; }
        public MovieViewModel(List<Movies> m)
        {
            this.TestCommand = new DelegateCommand<object>(TestcommandHandler);
            _m = m;
        }
        public List<Movies> lm
        {
            get
            {
                return _m;
            }
        }
    
    void TestcommandHandler(object obj)
    {
          // add your logic here
    }
    }
    
    使用Microsoft.Practices.Composite.Wpf.Commands; 只读列表; 公共ICommand TestCommand{get;set;} 公共电影视图模型(列表m) { this.TestCommand=新的DelegateCommand(TestcommandHandler); _m=m; } 公共列表lm { 得到 { 返回m; } } void TestcommandHandler(对象obj) { //在这里添加您的逻辑 } }
    在这种情况下,实现INotifyPropertyChanged接口有何帮助?在构造函数中为TestCommand赋值。此时如何订阅PropertyChanged事件?请参阅@Arcturus的答案:在项目模板中,您的DataContext将更改为显示的特定项目。要绑定到的命令位于父视图(视图模型)的数据上下文上,而不是项的数据上下文(它是
    Movie
    的单个实例)。此外,DataContext=“{Binding}”是reduntant:您正在将
    DataContext
    绑定到当前的整个数据上下文,它已经是:)