需求简述:我需要在DataTemplate内部使用来自ViewModel的DataContext方法来触发按钮的命令。
问题简述:模板化按钮的命令似乎只能绑定到项目本身的datacontext。WPF和Windows 8.1应用程序用于遍历可视树的语法似乎不起作用,包括ElementName和Ancestor binding。我非常希望我的按钮命令不要位于MODEL中。
附注:这是采用MVVM设计方法构建的。
下面的代码生成VIEW上的项目列表。该列表是每个列表项的一个按钮。
<ItemsControl x:Name="listView" Tag="listOfStories" Grid.Row="0" Grid.Column="1"
ItemsSource="{x:Bind ViewModel.ListOfStories}"
ItemTemplate="{StaticResource storyTemplate}"
Background="Transparent"
IsRightTapEnabled="False"
IsHoldingEnabled="False"
IsDoubleTapEnabled="False"
/>
在同一个VIEW的页面资源内,我创建了一个DataTemplate,其中包含有问题的按钮。我去掉了按钮内部大部分格式,例如文本,以便于在此处更容易阅读代码。关于按钮的所有内容都可以正常工作,除了列出的问题,即命令绑定。
<Page.Resources>
<DataTemplate x:Name="storyTemplate" x:DataType="m:Story">
<Button
Margin="0,6,0,0"
Width="{Binding ColumnDefinitions[1].ActualWidth, ElementName=storyGrid, Mode=OneWay}"
HorizontalContentAlignment="Stretch"
CommandParameter="{Binding DataContext, ElementName=Page}"
Command="{Binding Source={StaticResource Locator}}">
<StackPanel HorizontalAlignment="Stretch" >
<TextBlock Text="{x:Bind StoryTitle, Mode=OneWay}"
FontSize="30"
TextTrimming="WordEllipsis"
TextAlignment="Left"/>
</StackPanel>
</Button>
</DataTemplate>
</Page.Resources>
因为这是一个DataTemplate,所以DataContext已经被设置为组成列表的各个项(MODEL)。我需要做的是选择列表本身的DataContext(VIEWMODEL),以便我可以访问导航命令。
如果您对VIEW页面的代码有兴趣,请参见下面。
public sealed partial class ChooseStoryToPlay_View : Page
{
public ChooseStoryToPlay_View()
{
this.InitializeComponent();
this.DataContextChanged += (s, e) => { ViewModel = DataContext as ChooseStoryToPlay_ViewModel; };
}
public ChooseStoryToPlay_ViewModel ViewModel { get; set; }
}
我尝试使用ElementName进行设置,还有其他方法,但都失败了。当输入ElementName时,Intellisense会检测到“storyTemplate”作为选项,这是第一个代码块中显示的DataTemplate的名称。
我认为我的问题可能不是独一无二的,但我很难找到UWP的解决方案。如果这是一个简单的问题,那么请允许我提前道歉,但我已经花了将近两天的时间研究答案,但似乎没有任何适用于UWP的答案。
谢谢大家!