0

В проекте есть шаблон CollectionView, в нем описан DataTemplate элемента. Этот шаблон используется в нескольких View. Как забиндить для кнопки внутри DataTemplate команду, которая находится в нынешнем BindingContext для View, в котором CollectionView выводится?

Конкретно: в ResourceDictionary есть шаблон (ненужный контекст вырезал):

<Style TargetType="CollectionView" x:Key="FirstCollectionStyle">
                <Setter Property="ItemTemplate">
                    <DataTemplate>
                        <Grid x:DataType="models:Song">
                            <ImageButton Command="{TemplateBinding BindingContext.PlayPushedCommand }" CommandParameter="{Binding .}"/>
                        ...
                        </Grid>
                    </DataTemplate>
                </Setter>
            </Style>

В ViewModel:

public Command<Song> PlayPushedCommand { get => new Command<Song>(async (song) => await PlayPushed(song)); }
...
        private Task<bool> PlayPushed(Song song)
        {
            ...
        }

Кроме конкретно этой вьюмодели есть и другие с такими же командами внутри. Вопрос в том, как мне обратиться из Command ImageButton к команде именно модели, которая является на данный момент контекстом. Ведь через TemplateBinding я получу доступ к контексту коллекции, к которой принадлежит этот элемент.

looqey
  • 13
  • 4
  • CollectionView - это связующее звено между коллекцией и контролом, отображающим эту коллекцию. WPF создает CollectionView автоматически. Команды могут быть расположены там, куда указывает DataContext контрола, он может быть задан либо явно, либо наследоваться от родителя, внутри контрола для элемента коллекции DataContext устанавливается на сам элемент коллекции, то есть на данные, которые служат источником для отображаемого элемента. Обычно положение команд никак не связано с CollectionView, поэтому ваш вопрос не понятен, покажите код и разметку, и расскажите, что именно у вас не получается. – aepot Dec 05 '20 at 08:50
  • То, что WPF роли не играет, у них механизмы привязки +- одинаковые, отличие только в наименованиях, которые я думаю вы и сами сможете подправить. – EvgeniyZ Dec 05 '20 at 10:12
  • Не уверен, но возможно x:Reference поможет. тут 4-й пункт в статье – Pavel Popov Dec 05 '20 at 11:46
  • Я правильно понял, что у вас конфликт названий с System.Windows.Data.CollectionView. Лучше переименуйте свой класс, это меня и ввело в заблуждение в первом комментарии. – aepot Dec 05 '20 at 20:49
  • Конфликта не было - у меня в шаблоне указан TargetType, а не имя – looqey Dec 06 '20 at 13:31
  • Благодарю за ответы, нашел решение методом тыка: Command="{Binding PlayTappedCommand, Source={RelativeSource Mode=FindAncestorBindingContext, AncestorType={x:Type vm:MusicVM}}}". Для этого сделал одну вьюмодель для всех вью. – looqey Dec 06 '20 at 18:18
  • Вы не методом тыка делайте, а осмыслите то, что написали. Если перевести это в человеческий язык, то я думаю вы знаете, что в XAML и привязках есть скажем так, иерархия, вот то, что у вас внутри коллекции, устанавливает источник данных именно на объект этой коллекции и в этом случае вам надо перейти на уровень выше. Привязка, что я вам показал в дубликате, грубо говоря говорит следующее: "найди выше предка с типом ..., у которого возьми такое-то свойство.". Обычно тут достаточно элемента, в котором находится ваша коллекция (окно или Grid например), а у него вы обращаетесь к BindingContext. – EvgeniyZ Dec 06 '20 at 19:34
  • Методом тыка - не значит, что я не понимаю, я хотел использовать механизм поиска предка, но не знал, как это правильно сделать в Xamarin, там ведь нет понятия Window в AncestorType, как в WPF. Плюс, было несколько вьюмоделей - этим я отсекал себе путь поиска предка таким образом. С одной вьюмоделью на все вью получилось разрешить это так – looqey Dec 06 '20 at 21:23
  • *для всех типовых вью, в которых используется этот collectionview, конечно же, а не для всех подряд – looqey Dec 07 '20 at 04:46

0 Answers0