Как я могу привязать кнопку к команде модели представления из шаблона данных, который находится в Page.Resources?

В моем приложении, использующем Windows App SDK, я пытаюсь получить событие нажатия кнопки, чтобы вызвать команду в моей модели представления. Я заставил это работать, когда шаблон данных находится между и на странице, но он не будет работать, когда шаблон данных находится в Page.Resources. Мне нужно поместить некоторые шаблоны данных в Page.Resources, потому что мне нужно иметь несколько шаблонов данных в TreeView и использовать DataTemplateSelector, чтобы выбрать правильный в зависимости от типа элемента. У меня работает выбор шаблона, но я просто не могу заставить работать привязку кнопок. Похоже, привязка ElementName не может найти имя страницы. Может ли кто-нибудь показать мне, что я делаю неправильно?

      <Page.Resources>
    <DataTemplate x:Key="treeViewSFTemplate" x:DataType="models:SF">
            <TreeViewItem ItemsSource="{Binding OwnedSFEs}">
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="{Binding SFName}"/>
                    <Button Content="+">
                        <i:Interaction.Behaviors>
                            <core:EventTriggerBehavior EventName="Tapped">
                                <core:InvokeCommandAction Command="{Binding ElementName=sfSettingsPage, Path=ViewModel.AddNewSubfactorCommand}"/>
                            </core:EventTriggerBehavior>
                        </i:Interaction.Behaviors>
                    </Button>
                    <Button Content="-"/>
                </StackPanel>
            </TreeViewItem>
        </DataTemplate>

       
        <DataTemplate x:Key="treeViewSFETemplate" x:DataType="models:SFE">
        <TreeViewItem>
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding SFEName}"/>
                <Button Content="+">
                    <i:Interaction.Behaviors>
                        <core:EventTriggerBehavior EventName="Tapped">
                            <core:InvokeCommandAction Command="{Binding ElementName=thisPage, Path=ViewModel.DeleteSFECommand}"/>
                        </core:EventTriggerBehavior>
                    </i:Interaction.Behaviors>
                </Button>
                <Button Content="-"/>
            </StackPanel>
        </TreeViewItem>
    </DataTemplate>
</Page.Resources>

А затем в коде страницы ниже:

      <TreeView x:Name="MyTreeView" 
                          ItemsSource="{x:Bind ViewModel.SFList}" 
                          ItemTemplateSelector="{StaticResource treeViewDataTemplateSelector}" />

2 ответа

Причина такого поведения заключается в том, что вы обернули a в DataTemplate. Это приведет к тому, что он содержит sub-TreeViewItem в визуальном дереве, и вы не сможете получить доступ к правильному DataContext с именем элемента в вашей кнопке. Пожалуйста, удалите TreeViewItemиз вашего кода.

Нравиться:

       <DataTemplate x:Key="treeViewSFETemplate" x:DataType="models:SFE">
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="{Binding SFEName}"/>
            <Button Content="+">
                <i:Interaction.Behaviors>
                    <core:EventTriggerBehavior EventName="Tapped">
                        <core:InvokeCommandAction Command="{Binding ElementName=thisPage, Path=ViewModel.DeleteSFECommand}"/>
                    </core:EventTriggerBehavior>
                </i:Interaction.Behaviors>
            </Button>
            <Button Content="-"/>
        </StackPanel>
</DataTemplate>

Предполагая модель представления MyViewModelдля страницы привязано к свойству страницы и MyItemViewModelэто тип данных элемента в коллекции. CommandParameterпривязка связывает модель представления элемента:

      <Page
 ...
 x:Name="MyPage"
 ...
  <Page.Resources>
  ...
    <DataTemplate x:Key="MyDataTemplate" x:DataType="vm:MyItemViewModel>
    ...
      <Button
      ...
        Command="{Binding ElementName=MyPage, Path=DataContext.MyCommand}"
        CommandParameter="{Binding}"
        ...

Изменения стоимости имущества DataContextможно проверить, добавив обработчик событий после InitializeComponent()в конструкторе страницы:

      public MyPage()
{
  InitializeComponent();
  ...
  DataContextChanged += MyPage_DataContextChanged;
  ...
}

void MyPage_DataContextChanged(FrameworkElement sender, DataContextChangedEventArgs args)
{
  if (DataContext is MyViewModel vm)
  {
  }
}
Другие вопросы по тегам