我想制作一个HamburgerMenu。这里是XAML。
<SplitView Grid.Row="1" HorizontalAlignment="Left">
<SplitView.Content>
<ListView>
<ItemsControl x:Name="NavItemsControl">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel></StackPanel>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock FontFamily="Segoe MDL2 Assets" Text="{Binding Icon}"></TextBlock>
<TextBlock Text="{Binding Content}" Grid.Column="1"></TextBlock>
</Grid>
</Button>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ListView>
</SplitView.Content>
</SplitView>
这里有代码:
public class NavItems : INotifyPropertyChanged
{
string _Icon;
public string Icon
{
set
{
_Icon = value;
OnPropertyChanged("Icon");
}
get
{
return _Icon;
}
}
string _Content;
public string Content
{
set
{
_Content = value;
OnPropertyChanged("Content");
}
get
{
return _Content;
}
}
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
public event PropertyChangedEventHandler PropertyChanged;
}
在设置了NavItemsControl的ItemSource之后,我可以轻松地绑定诸如Icon或Content之类的属性。唯一的问题是我想绑定click事件
按钮,但我不知道如何绑定它。
我尝试使用委托来绑定click事件,但它不起作用并报告错误。
你能帮我吗?
谢谢
答案 0 :(得分:4)
在我们回答您的问题之前,让我们先修复您的XAML。您正在使用ListView
来换行ItemsControl
,这是不必要的。实际上,ListView
本身继承自ItemsControl
,基本上是它的一个更强大的版本。在您的情况下,ItemsControl
就足够了,因此您可以安全地删除ListView
包装。
由于您在模板中使用了Button
,因此您可以在ClickCommand
中创建ICommand
(类型为NavItems
)并绑定Button
' s Command
属性。
<Button Command="{Binding ClickCommand}" />
互联网上有大量资源可供您ICommand
实施,请查看UWP Toolkit的工作方式。
旁注
我个人不喜欢使用SelectionChanged
,因为它是一个可由数据更改触发的数据驱动的事件。这可能是不可预测的并且容易出错。此外,除非您手动重置SelectedIndex
,否则无法重新选择相同的项目。按钮Click
(或来自ItemClick
的{{1}})是输入驱动的事件,只能(在大多数情况下)由用户操作调用,很少给你任何副作用。
答案 1 :(得分:1)
要为您注册事件按钮单击,您需要添加并定义ListView的Selection Changed事件。所以你的代码应该是这样的:
<SplitView Grid.Row="1" HorizontalAlignment="Left">
<SplitView.Content>
<ListView x:Name="itemListView" SelectionChanged="ItemListView_SelectionChanged">
<ItemsControl x:Name="NavItemsControl">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel></StackPanel>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock FontFamily="Segoe MDL2 Assets" Text="{Binding Icon}"></TextBlock>
<TextBlock Text="{Binding Content}" Grid.Column="1"></TextBlock>
</Grid>
</Button>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ListView>
</SplitView.Content>
</SplitView>
C#代码背后应该是这样的:
private void ItemListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if(itemListView.SelectedItem!=null){
Debug.WriteLine(itemListView.SelectedIndex + " Index selected");
// More logic here
}
}
答案 2 :(得分:0)
我尝试用ICommand做,但代码看起来很丑陋。仅供参考。
<SplitView Grid.Row="1" HorizontalAlignment="Left">
<SplitView.Content>
<ItemsControl x:Name="NavItemsControl">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel></StackPanel>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Command="{Binding ClickCommand}" Padding="10,20" Background="Transparent">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock FontFamily="Segoe MDL2 Assets" Text="{Binding Icon}" VerticalAlignment="Center"></TextBlock>
<TextBlock Text="{Binding Content}" Grid.Column="1" VerticalAlignment="Center" Padding="20,0,0,0"></TextBlock>
</Grid>
</Button>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</SplitView.Content>
</SplitView>
代码背后:
public MainPage()
{
InitializeComponent();
NavItems.ClickVoidDelegate CD = new NavItems.ClickVoidDelegate(()=> { Debug.WriteLine("123"); });
List<NavItems> NavItemsList = new List<NavItems>()
{
new NavItems(){
Icon="\xE166",Content="Open",ClickCommand=new NavItems.ClickCommandClass(CD)
}
};
NavItemsControl.ItemsSource = NavItemsList;
}
public class NavItems : INotifyPropertyChanged
{
string _Icon;
public string Icon
{
set
{
_Icon = value;
OnPropertyChanged("Icon");
}
get
{
return _Icon;
}
}
string _Content;
public string Content
{
set
{
_Content = value;
OnPropertyChanged("Content");
}
get
{
return _Content;
}
}
ClickCommandClass _ClickCommand;
public ClickCommandClass ClickCommand
{
get;
set;
}
public class ClickCommandClass : ICommand
{
public ClickCommandClass(ClickVoidDelegate ClickVoid)
{
_ClickVoid = ClickVoid;
}
ClickVoidDelegate _ClickVoid;
public void Execute(object parameter)
{
if (_ClickVoid != null)
{
_ClickVoid();
}
}
public bool CanExecute(object parameter)
{
return true;
}
public event EventHandler CanExecuteChanged;
}
public delegate void ClickVoidDelegate();
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
public event PropertyChangedEventHandler PropertyChanged;
}