1

在我使用 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}" />
4

2 回答 2

2

此行为的原因是您将 a 包装TreeViewItem在 DataTemplate 中。这将导致TreeViewItem在可视树中包含子 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>
于 2022-01-31T05:14:05.650 回答
1

假设页面的视图模型MyViewModel绑定到页面的DataContext属性并且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)
  {
  }
}
于 2022-01-31T11:30:42.077 回答