我正在搜索互联网,了解如何为ListView
添加上下文菜单。到目前为止,我发现了一个实际显示上下文的文件
<ListView>
...
RightTapped="ContactsListView_RightTapped" >
...
<ListView.Resources>
<MenuFlyout x:Name="allContactsMenuFlyout">
<MenuFlyout.Items>
<MenuFlyoutItem x:Name="Edit" Text="Edit"/>
<MenuFlyoutItem x:Name="Remove" Text="Remove" Click="Remove_Click"/>
</MenuFlyout.Items>
</MenuFlyout>
</ListView.Resources>
...
</ListView>
private void ContactsListView_RightTapped(object sender, RightTappedRoutedEventArgs e) {
ListView listView = (ListView)sender;
allContactsMenuFlyout.ShowAt(listView, e.GetPosition(listView));
}
private void Remove_Click(object sender, RoutedEventArgs e) {
}
问题是我无法获得显示上下文菜单的项目。另一个问题是上下文菜单也显示在列表视图项之外(例如,在边界上)。由于触发的事件是RightTapped,我不确定是否会在长按移动设备上显示上下文菜单。我无法测试它,因为我的模拟器当前不工作。由于它应该是通用的Windows应用程序,我期待一些非常简单有效的方法为ListView项目创建上下文菜单。
答案 0 :(得分:15)
问题是我无法获得显示上下文菜单的项目。
对于此问题,如果您将数据添加到ListView
,请执行以下操作:
<ListView RightTapped="ListView_RightTapped">
<x:String>First Item</x:String>
<x:String>Second Item</x:String>
<x:String>Third Item</x:String>
<x:String>Fourth Item</x:String>
<ListView.Resources>
<MenuFlyout x:Name="allContactsMenuFlyout">
<MenuFlyout.Items>
<MenuFlyoutItem x:Name="Edit" Text="Edit" />
<MenuFlyoutItem x:Name="Remove" Text="Remove" Click="Remove_Click" />
</MenuFlyout.Items>
</MenuFlyout>
</ListView.Resources>
</ListView>
您可以在RightTapped
事件中获取该项目的上下文,如下所示:
private void ListView_RightTapped(object sender, RightTappedRoutedEventArgs e)
{
ListView listView = (ListView)sender;
allContactsMenuFlyout.ShowAt(listView, e.GetPosition(listView));
var a = ((FrameworkElement)e.OriginalSource).DataContext;
}
在这种情况下,&#34; a&#34;将直接获取被点击项目的字符串格式内容。
如果您使用ListView
将数据添加到DataTemplate
,请执行以下操作:
<ListView RightTapped="ListView_RightTapped" ItemsSource="{x:Bind list}">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding text}" />
</DataTemplate>
</ListView.ItemTemplate>
<ListView.Resources>
<MenuFlyout x:Name="allContactsMenuFlyout">
<MenuFlyout.Items>
<MenuFlyoutItem x:Name="Edit" Text="Edit" />
<MenuFlyoutItem x:Name="Remove" Text="Remove" Click="Remove_Click" />
</MenuFlyout.Items>
</MenuFlyout>
</ListView.Resources>
</ListView>
通常在使用DataTemplate
时,我们按ObservableCollection
添加数据:
private ObservableCollection<List> list = new ObservableCollection<List>();
public MainPage()
{
this.InitializeComponent();
list.Clear();
list.Add(new List { text = "Item 1" });
list.Add(new List { text = "Item 2" });
list.Add(new List { text = "Item 3" });
list.Add(new List { text = "Item 4" });
list.Add(new List { text = "Item 5" });
}
&#34;列表&#34;这里的课程非常简单:
public class List
{
public string text { get; set; }
}
然后我们也可以在DataContext
事件中获取RightTapped
:
private void ListView_RightTapped(object sender, RightTappedRoutedEventArgs e)
{
ListView listView = (ListView)sender;
allContactsMenuFlyout.ShowAt(listView, e.GetPosition(listView));
var a = ((FrameworkElement)e.OriginalSource).DataContext;
}
但这一次,&#34; a&#34;实际上是&#39; List&#39;对象(请参阅&#34;列表&#34;类),因为项目的内容现在是&#39;列表&#39;对象,不再是字符串了。所以我们可以得到这个对象的text属性:
private void ListView_RightTapped(object sender, RightTappedRoutedEventArgs e)
{
ListView listView = (ListView)sender;
allContactsMenuFlyout.ShowAt(listView, e.GetPosition(listView));
var a = ((FrameworkElement)e.OriginalSource).DataContext as List;
var content = a.text;
}
我认为最终你想编辑Flyout
的按钮点击事件中的内容,你可以这样做:
private string content;
private void ListView_RightTapped(object sender, RightTappedRoutedEventArgs e)
{
ListView listView = (ListView)sender;
allContactsMenuFlyout.ShowAt(listView, e.GetPosition(listView));
var a = ((FrameworkElement)e.OriginalSource).DataContext as List;
content = a.text;
}
private void Remove_Click(object sender, RoutedEventArgs e)
{
foreach (var item in list.ToList())
{
if (item.text == content)
{
list.Remove(item);
}
}
content = "";
}
另一个问题是上下文菜单也显示在列表视图项之外(例如,在边框上)。
你能解释一下吗?我无法理解它。您的意思是在Flyout
中显示内容?如果是这样,我认为上面的方法可以解决这个问题。如果没有,你可以发表评论,我会看看是否可以解决这个问题。
由于触发的事件是RightTapped,我不确定是否会在长按移动设备上显示上下文菜单。
我认为&#34;长按&#34; event在这里表示Holding
这样的事件?
private void ListView_Holding(object sender, HoldingRoutedEventArgs e)
{
ListView listView = (ListView)sender;
allContactsMenuFlyout.ShowAt(listView, e.GetPosition(listView));
var a = ((FrameworkElement)e.OriginalSource).DataContext as List;
content = a.text;
}
我只是在移动模拟器上测试它,它工作正常。虽然我在这里写了一个很长的答案,但关键点很简单,你可以使用((FrameworkElement)e.OriginalSource).DataContext
来获取项目的上下文。
答案 1 :(得分:3)
使用Command而不是Click事件。您可以在CommandParameter中传递单击的项目
<MenuFlyout x:Name="allContactsMenuFlyout">
<MenuFlyout.Items>
<MenuFlyoutItem x:Name="Edit" Text="Edit"/>
<MenuFlyoutItem x:Name="Remove" Text="Remove" Command="{Binding Path=DataContext.DeleteItemTappedCommand , ElementName=ListViewName}" CommandParameter="{Binding }"/>
</MenuFlyout.Items>
</MenuFlyout>
In viewModel.cs
public DelegateCommand<object> DeleteItemTappedCommand { get; set; }
public viewModel()
{
DeleteItemTappedCommand = new DelegateCommand<object>(DeleteItemClicked);
}
private void DeleteItemClicked(object obj)
{
//Your code. Here obj is clicked item
}
答案 2 :(得分:0)
在datatemplate中添加弹出按钮。使用命令处理事件。 请在此处查看示例代码:
<DataTemplate x:Name="ListItemTemplate" >
<Grid x:Name="gridItem" RightTapped="gridItem_RightTapped">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Image Name="imgProduct" Width="50" Height="50" Grid.Column="0" Source="{Binding ProductUrl}" Margin="0,5,10,5" VerticalAlignment="Center" ></Image>
<TextBlock Name="tbName" Text="{Binding Name}" Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Stretch" ></TextBlock>
<FlyoutBase.AttachedFlyout>
<MenuFlyout>
<MenuFlyoutItem Text="Delete" Command="{Binding DataContext.DeleteCommand, ElementName=contentGrid}" CommandParameter="{Binding}" />
</MenuFlyout>
</FlyoutBase.AttachedFlyout>
</Grid>
</DataTemplate>
代码背后:
private void gridItem_RightTapped(object sender, RightTappedRoutedEventArgs e)
{
FlyoutBase.ShowAttachedFlyout(sender as FrameworkElement);
}
您可以在此处获得完整的解决方案:https://code.msdn.microsoft.com/How-to-implement-flyout-ef52517f