我正在编写通用应用程序,我希望它使用新的“汉堡”风格菜单。要填充我为应用程序创建的汉堡包菜单,我使用的是当前托管在Azure上的JSON数据源。我可以很好地下载数据,将它放在ObservableCollection中并绑定它 - 但是我需要汉堡菜单中的按钮来了解点击时列表视图的位置(索引)。
我正在使用绑定到ListView的RelayCommand来处理其按钮单击操作。
我的网页XAML
x:Class="IOTLightsUniversal.MainPage"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:IOTLightsUniversal"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
RequestedTheme="Dark"
Name="MPage">
<Page.Resources>
<MenuFlyout x:Key="FlyoutBase1"/>
</Page.Resources>
<SplitView x:Name="MainSplitView" DisplayMode="CompactOverlay" IsPaneOpen="False" CompactPaneLength="50" OpenPaneLength="225">
<SplitView.Pane>
<StackPanel Background="Gray" Name="Root">
<Button x:Name="HamburgerButton" FontFamily="Segoe MDL2 Assets" Content=""
Width="50" Height="50" Background="Transparent" Command="{Binding HamburgerListItemCommand}" Click="HamburgerButton_Click"/>
<ListView Padding="-12,0,0,0" x:Name="HamburgerList" Foreground="White" SelectionChanged="HamburgerList_SelectionChanged">
<ListView.ItemTemplate>
<DataTemplate x:Name="HamburgerItemTemplate">
<StackPanel Orientation="Horizontal" Padding="0">
<Button Margin="-0,0,0,0" FontFamily="Segoe MDL2 Assets" Command="{Binding ElementName=Root, Path=DataContext.HamburgerListItemCommand}" Content="" Width="50" Height="50" Background="Transparent" x:Name="HamburgerButton" />
<TextBlock x:Name="HamburgerText" Text="{Binding DeviceName}" FontSize="18" Foreground="Black" VerticalAlignment="Center" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackPanel>
</SplitView.Pane>
<SplitView.Content>
<Grid>
<TextBlock Text="SplitView Content" FontSize="54" Foreground="Black"
HorizontalAlignment="Center" VerticalAlignment="Center"/>
<TextBlock Text="" FontFamily="Segoe MDL2 Assets" Foreground="Black" FontSize="54"/>
</Grid>
</SplitView.Content>
</SplitView>
我的网页.xaml.cs代码隐藏
public sealed partial class MainPage : Page
{
private NavigationHelper navigationHelper;
public ObservableCollection<AzureDataItem> DefaultViewModel = new ObservableCollection<AzureDataItem>();
public MainPage()
{
this.InitializeComponent();
HamburgerListItemCommand = new RelayCommand(HamburgerListButtonClick); //new RelayCommand(this.HamburgerListButtonClick);
}
public MainPage(Frame frame)
{
this.InitializeComponent();
MainSplitView.Content = frame;
(MainSplitView.Content as Frame).Navigate(typeof(MicPage));
getData();
HamburgerListItemCommand = new RelayCommand(this.HamburgerListButtonClick);
HamburgerList.ItemsSource = DefaultViewModel;
}
private async void getData()
{
var AzureDataItems = await AzureDataSource.GetDataItemsAsync();
foreach (AzureDataItem adi in AzureDataItems)
{
DefaultViewModel.Add(adi);
}
}
private void HamburgerButton_Click(object sender, RoutedEventArgs e)
{
MainSplitView.IsPaneOpen = !MainSplitView.IsPaneOpen;
}
private void HamburgerListButtonClick()
{
/*What should I put here?*/
}
public ICommand HamburgerListItemCommand
{
get;
private set;
}
}
到目前为止,我已经尝试了第二个代码片段:In a ListView containing Buttons, how to get Index of the clicked one?,但.Parent调用获取按钮的父StackPanel而不是ListView,因此它不起作用。
提前感谢任何解决方案/建议!
答案 0 :(得分:0)
您可以使用&#34;参数化&#34;命令并为按钮指定CommandParameter属性。
<Button Margin="-0,0,0,0"
FontFamily="Segoe MDL2 Assets"
Command="{Binding ElementName=Root, Path=DataContext.HamburgerListItemCommand}"
CommandParameter="{Binding}"
Content=""
Width="50"
Height="50"
Background="Transparent"
x:Name="HamburgerButton" />
如您所见,我已将CommandParameter属性绑定到当前的DataContext。
并在您的主类中:
public MainPage() {
this.InitializeComponent();
HamburgerListItemCommand = new Command<object>(HamburgerListButtonClick);
}
private void HamburgerListButtonClick(object parameter) {
AzureDataItem item = parameter as AzureDataItem;
// Now you have access to the clicked item
int index = DefaultViewModel.IndexOf(item);
}
如您所见,我使用了Command类,因为我无法访问您使用的RelyCommand源,如果它接受参数则不会。这是Command类的源代码:
class Command : ICommand {
public event EventHandler CanExecuteChanged;
private Action action;
private bool canExecute = true;
public Command(Action action, bool canExecute = true) {
if (action == null) {
throw new ArgumentNullException("action");
}
this.action = action;
this.canExecute = canExecute;
}
internal bool CanExecuteInternal {
get {
return this.canExecute;
}
set {
if (this.canExecute != value) {
this.canExecute = value;
this.OnCanExecuteChanged(EventArgs.Empty);
}
}
}
public bool CanExecute(object parameter) {
return this.canExecute;
}
public void Execute(object parameter) {
this.action();
}
private void OnCanExecuteChanged(EventArgs e) {
if (this.CanExecuteChanged != null) {
this.CanExecuteChanged(this, e);
}
}
}
class Command<T> : ICommand {
public event EventHandler CanExecuteChanged;
private Action<T> action;
private bool canExecute = true;
public Command(Action<T> action, bool canExecute = true) {
if (action == null) {
throw new ArgumentNullException("action");
}
this.action = action;
this.canExecute = canExecute;
}
internal bool CanExecuteInternal {
get {
return this.canExecute;
}
set {
if (this.canExecute != value) {
this.canExecute = value;
this.OnCanExecuteChanged(EventArgs.Empty);
}
}
}
public bool CanExecute(object parameter) {
return this.canExecute;
}
public void Execute(object parameter) {
this.action((T)parameter);
}
private void OnCanExecuteChanged(EventArgs e) {
if (this.CanExecuteChanged != null) {
this.CanExecuteChanged(this, e);
}
}
}