C# MVVM WPF中的ICommand
我正在看这个MVVM的东西,我面临一个问题 情况很简单 我的index.xaml页面中有以下代码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
<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接口
其次,电影对象没有对父对象的引用
您可以通过三种不同的方式解决此问题:
?怎么样
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
绑定到当前的整个数据上下文,它已经是:)