Как отправить ItemControl Item для вложенных коллекций - PullRequest
0 голосов
/ 27 ноября 2018

У меня есть ItemControl, связанный с ObservableCollection<ObservableCollection<BookModel>>.Каждый элемент в глубоком ItemControl имеет кнопку.Я реализовал команду, которая срабатывает при каждом нажатии кнопки.
Моя проблема в том, что я не знаю, какой параметр я должен передать методу выполнения, чтобы узнать, какой элемент вызвал команду.То есть, если кнопка функционирует как кнопка «Добавить книгу», я хочу знать, куда мне вставить объект BookModel

<UserControl.Resources>
<DataTemplate x:Key="BooksViewTemplate">
    <StackPanel>
        <TextBlock>
            <!-- This is where I bind data to the BookModel -->
        </TextBlock>
        <Button x:Name="AddNewBook"
                Command="{Binding ElementName=LayoutRoot, Path = DataContext.AddBookCommand}"
                <!-- CommandParameter=  -->
        />
    </StackPanel>
</<DataTemplate>

<DataTemplate x:Key="DataTemplate_level1">
    <StackPanel>
        <ItemsControl ItemsSource="{Binding}" ItemTemplate="{DynamicResource BooksViewTemplate}">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <StackPanel Orientation="Vertical">
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
        </ItemsControl>
    </StackPanel>
</DataTemplate>
</UserControl.Resources>

<Grid x:Name="LayoutRoot">
<ItemsControl ItemsSource="{Binding Books}" ItemTemplate="{DynamicResource DataTemplate_level1}" DataContext="{Binding}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel Orientation="Horizontal"/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
</ItemsControl>

public ICommand AddBookCommand
{
    get
    {
        return _addBookCommnad ?? (_addBookCommand = new CmandHandler<object>((par) => AddBookAction(par), _canExecute));
    }
}

public void AddBookAction(object obj)
{
    //This is where I want to add a new BookModel to the 
    IObservableCollection<IObservableCollection<BookModel>> at the location 
    given by the pressed button
}

1 Ответ

0 голосов
/ 27 ноября 2018

Вы можете использовать свойство AlternationIndex для получения индекса.Просто установите AlternationCount в ItemsControl на int.MaxValue:

<ItemsControl ItemsSource="{Binding yourcollection}" AlternationCount="2147483647">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Path=(ItemsControl.AlternationIndex), RelativeSource={RelativeSource Mode=TemplatedParent}}"/>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

Если вы передадите элемент в качестве CommandParameter и выполните поиск в своей коллекции, он будет работать, если у вас нет без дубликатов ссылок. в коллекции, в противном случае она не будет выполнена (вы не будете знать, какой экземпляр следует использовать).
Для вложенной коллекции вы можете получить доступ к индексу следующим образом:

<ItemsControl ItemsSource="{Binding ColOfCol}" AlternationCount="2147483647">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <ItemsControl ItemsSource="{Binding }" AlternationCount="2147483647">
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <TextBlock>
                            <TextBlock.Text>
                                <MultiBinding Converter="{StaticResource multivalcnv}">
                                    <Binding Path='(ItemsControl.AlternationIndex)' RelativeSource="{RelativeSource AncestorType=ContentPresenter, AncestorLevel=2}"></Binding>
                                    <Binding Path='(ItemsControl.AlternationIndex)' RelativeSource="{RelativeSource AncestorType=ContentPresenter, AncestorLevel=1}"></Binding>
                                </MultiBinding>
                            </TextBlock.Text>
                        </TextBlock>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

public class MultValConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        if (values.Length == 2)
        {
            //return (values[0], values[1]); //For the ViewModel
            return (values[0], values[1]).ToString(); //For the UI example
            }
        else
            return Binding.DoNothing;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException("It's a one way converter.");
    }
}
...