2016-04-20 83 views
6

我正在搜索如何爲ListView添加上下文菜單的互聯網。到目前爲止,我發現其中一個實際顯示上下文UWP 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項目創建上下文菜單的一些非常簡單而有效的方法。

回答

9

的問題是我不能夠得到在其上顯示的上下文菜單項。

對於這個問題,如果你將數據添加到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; 
} 

在這種情況下,「a」將直接得到點擊項目的字符串格式內容。

如果您在使用DataTemplate這樣的數據添加到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> 

,通常,我們通過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" }); 
} 

「列表」 級相當這裏簡單測試:

public class List 
{ 
    public string text { get; set; } 
} 

那麼我們也可以在RightTapped事件而得到DataContext

private void ListView_RightTapped(object sender, RightTappedRoutedEventArgs e) 
{ 
    ListView listView = (ListView)sender; 
    allContactsMenuFlyout.ShowAt(listView, e.GetPosition(listView)); 
    var a = ((FrameworkElement)e.OriginalSource).DataContext; 
} 

但是這一次,「一」其實是「列表」對象(請參閱「清單」級)的項目中,因爲該項目的內容現在是一個'List'對象,不再是一個字符串。因此,我們可以得到這個物體的像這樣的文本屬性:

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,我不確定上下文菜單是否會長時間顯示在移動設備上。

我認爲這裏的「長按」事件表示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來獲取該項目的上下文。

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 
} 
+0

THX的響應。我要試一下。但觸發此事件的事件仍然右鍵單擊列表視圖。所以它會被觸發e。 G。當我在列表視圖或邊框上右鍵單擊某個組的標題時。我期待着很容易實現的東西,因爲這是常用的功能。 – miskohut

+0

綁定是有意義的,但它總是'空'。沒有任何成功讓'Command'屬性附加到任何東西。 –

+0

嘗試從棱鏡框架中使用'Behaviors'和'InvokeCommandAction' – Archana

0

在數據模板中添加彈出窗口。使用命令來處理事件。 見示例代碼瀏覽:

<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