Search code examples
c#wpfmvvmbindingcommandparameter

How to get object from ObservableCollection within clicking it in UI?


I've got a field of TextBlocks that I'm displaying in a Uniform Grid, when I click one a Command triggers. How can I now get the specific object that was clicked from the displayed Collection?

For more information check my previous question about command on the textblock: C# MVVM How to add Command to TextBlock

XAML:

<ItemsControl ItemsSource="{Binding CellCollection}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <TextBlock Background="{Binding Path=CellBackgroundColor}">
                <TextBlock.InputBindings>
                <MouseBinding Command="{Binding DataContext.TestCommand, RelativeSource={RelativeSource AncestorType=ItemsControl}}" MouseAction="LeftClick"/>
                </TextBlock.InputBindings>
            </TextBlock>                       
        </DataTemplate>
    </ItemsControl.ItemTemplate>
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
              <UniformGrid Grid.Row="0" Rows="25" Columns="25">
        </UniformGrid>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
</ItemsControl>

ViewModel:

public ObservableCollection<Cell> CellCollection { get; set; }

public MainWindowViewModel()
{
    StartCommand = new RelayCommand(Start);
    StopCommand = new RelayCommand(Stop);
    TestCommand = new RelayCommand(Test);
    CellCollection = new ObservableCollection<Cell>();

    //begins with 1 not 0
    //generates 625 cells for the field (25x25)
    for (int iRow = 1; iRow < 26; iRow++)
    {
        for (int iColumn = 1; iColumn < 26; iColumn++)
        {
            CellCollection.Add(new Cell() { Row = iRow, Column = iColumn, IsAlive = false, CellBackgroundColor = new SolidColorBrush(Colors.Transparent) });
        }
    }           
}

I tried following thing but it didnt work out:

<MouseBinding CommandParameter="{Binding CTest}" Command="{Binding DataContext.TestCommand, RelativeSource={RelativeSource AncestorType=ItemsControl}}" MouseAction="LeftClick"/>

Property

Cell _CTest;
public Cell CTest
{
    get
    {
        return _CTest;
    }
    set
    {
        if(_CTest != value)
        {
            _CTest = value;
            RaisePropertyChanged("CTest");
        }
    }
}

void Test(object parameter)
{
    Cell test = CTest;
}

Solution

  • bind CommandParameter in MouseBinding directly to item of DataTemplate:

    <MouseBinding 
        Command="{Binding DataContext.TestCommand, RelativeSource={RelativeSource AncestorType=ItemsControl}}" 
        CommandParameter="{Binding}" 
        MouseAction="LeftClick"/>
    

    command method will receive it via parameter:

    void Test(object parameter)
    {
        Cell test = (Cell)parameter;
    }