ICommand in MVVM WPF

I look at this MVVM stuff and I ran into a problem.

The situation is pretty simple.

I have the following code on index.xaml page

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

and in my index.xaml.cs

...

InitializeComponent (); base.DataContext = new MovieViewModel (ent.Movies.ToList ()); ....

and here is my 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;
        }
    }
}

finally,

here is my xaml movieview control

    <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>

So the problem is that if I set the ItemsSource on Binding

doing nothing

if I set ItemsSource = "{Binding lm}"

it fills my itemsControl, but the command (Command = "{Binding Path = TestCommand}") does not work.

Of course, this does not work, because TestCommand does not belong to my Object Movies.

So finally my question is:

What do I need to pass to ItemsControl in order to make it work?

thanks in advance

+3
6

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

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

RelativeSource , .

- , .

+1

, DataContext , , DataContext.. - , DataTemplate, , .. RelativeSource...

, .

+4

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 , , . Dependency, INotifyPropertyChanged..

-, Movie .

:

  • Bind : ie.. ParentMovieModel, :

    { = ParentMovieModel.TestCommand}

  • ElementName : , DataContext, : i.e Root. ElementName :

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

  • RelativeSource : , ...

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

+2
//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
}
}
+1

<ItemsControl ItemsSource="{Binding Path=lm}">?

0

ItemsSource = "{Binding Path = lm}" >

itemsControl , MovieViewModel

System.Windows.Data: 39: BindingExpression: TestCommand 'object' '' Movies '(HashCode = 1031007)'. BindingExpression: Path = TestCommand; DataItem = '' (HashCode = 1031007); 'Button' (Name= ''); target "Command" ( "ICommand" )

- Title Director

0

Source: https://habr.com/ru/post/1704711/


All Articles