3

我正在查看这个 MVVM 的东西,我遇到了一个问题。

情况很简单。

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

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

在我的 index.xaml.cs

...

初始化组件();base.DataContext = new 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;
        }
    }
}

最后

这是我的控制 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>

所以我遇到的问题是,如果我在 Binding 设置 ItemsSource

它什么也没做

如果我设置 ItemsSource="{Binding lm}"

它填充了我的 itemsControl 但命令 (Command="{Binding Path=TestCommand}" ) 不起作用。

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

所以最后我的问题是,

我需要将什么传递给 ItemsControl 才能使其正常工作?

提前谢谢

4

6 回答 6

4

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

希望能解释一些事情..

于 2009-03-13T14:13:27.760 回答
2

尝试实现 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));
        }
    }    
}

发生的情况是 TestCommand 有一个值,并且 UI 没有收到发生更改的通知。在控件上,您使用 Dependency 属性解决此问题,在数据对象上,您可以使用 INotifyPropertyChanged 接口。

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

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

  1. 在 Movie 上有一个对模型的引用,并使 Bind 路径如下所示:即.. 如果您的属性名为 ParentMovieModel,那么您的 Binding 将如下所示:

    {绑定路径=ParentMovieModel.TestCommand}

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

    {绑定元素名=根,路径=DataContext.TextCommand}

  3. 像这样基于RelativeSource进行绑定:按类型查找父控件,并使用与上述相同的路径...

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

于 2009-03-13T10:16:09.203 回答
1

得到它的工作

这是事情

 <ItemsControl DataContext="{Binding}" ItemsSource="{Binding lm}">

 Command="{Binding Path=DataContext.TestCommand, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" 

所以RelativeSource 是我错过的东西。

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

于 2009-03-13T11:15:50.120 回答
1
//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
}
}
于 2010-10-02T05:48:49.343 回答
0

怎么样<ItemsControl ItemsSource="{Binding Path=lm}">

于 2009-03-13T10:54:58.000 回答
0

在 ItemsSource="{Binding Path=lm}"> 的情况下

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

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

System.Windows.Data 错误:39:BindingExpression 路径错误:在“对象”“电影”(HashCode=1031007)上找不到“TestCommand”属性。绑定表达式:路径=测试命令;DataItem='电影' (HashCode=1031007); 目标元素是 'Button' (Name=''); 目标属性是“命令”(类型“ICommand”)

Movies 是我的实体对象,仅拥有 Title 和 Director 属性

于 2009-03-13T11:02:49.793 回答