3

私はこのMVVMのものを見ていますが、問題に直面しています。

状況は非常に単純です。

index.xaml ページに次のコードがあります。

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

そして私のindex.xaml.csで

...

InitializeComponent(); 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>

したがって、私が抱えている問題は、ItemsSource を Binding に設定した場合です。

それは何もしません

ItemsSource="{Binding lm}" を設定した場合

それは私のitemsControlに値を設定しますが、コマンド(Command="{Binding Path=TestCommand}")は機能しません。

もちろん、TestCommand は私のエンティティ オブジェクト Movies に属していないため、機能しません。

最後に私の質問は、

ItemsControl を機能させるには何を渡す必要がありますか?

事前にThx

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 インターフェイスを使用できます。

次に、Movie オブジェクトには親オブジェクトへの参照がありません。

この問題は、次の 3 つの方法で解決できます。

  1. Movie のモデルへの参照を持ち、Bind パスを次のようにします。つまり、プロパティの名前が ParentMovieModel の場合、Binding は次のようになります。

    {バインディング パス=ParentMovieModel.TestCommand}

  2. 次のように、ElementName に基づいてバインドを作成します。DataContext を設定した親コントロールを検索し、名前を付けます。つまり、Root です。次のように、ElementName に基づいてバインディングを作成します。

    {Binding ElementName=ルート、パス=DataContext.TextCommand}

  3. 次のように RelativeSource に基づいてバインディングを作成します。親コントロールをタイプ別にシークアップし、上記と同じパスを使用します...

    {Binding 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 に答える