我正在製作一個winodws 8手機應用程序,並嘗試從Windows Phone工具包獲取上下文菜單。上下文菜單使用Mvvm保持錯誤的對象
我一直在關注這個tutorial但不是列表框中我使用的是內置到WP8一個長長的清單選擇
<DataTemplate x:Key="GroceryListItemTemplate">
<StackPanel Grid.Column="1" Grid.Row="1">
<TextBlock x:Name="tbName" TextWrapping="Wrap" Text="{Binding Name}" FontSize="32"/>
<TextBlock x:Name="tbProductInfo" TextWrapping="Wrap" Text="{Binding ProductInfoLabel}" HorizontalAlignment="Left"/>
</StackPanel>
<toolkit:ContextMenuService.ContextMenu>
<toolkit:ContextMenu>
<toolkit:MenuItem Header="Edit"
Command="{Binding GroceryItemsVm.EditGroceryItemCmd, Source={StaticResource Locator}}"
CommandParameter="{Binding}"/>
<toolkit:MenuItem Header="Delete" Command="{Binding GroceryItemsVm.DeleteGroceryItemCmd, Source={StaticResource Locator}}"
CommandParameter="{Binding}"/>
</toolkit:ContextMenu>
</toolkit:ContextMenuService.ContextMenu>
</DataTemplate>
以上是剝奪了我的代碼看起來像
這裏是下降我的列表選擇
<phone:LongListSelector IsGroupingEnabled="True" ItemsSource="{Binding GroceryItems}" HideEmptyGroups="True" LayoutMode="List" Grid.Row="1">
<phone:LongListSelector.ItemTemplate>
<StaticResource ResourceKey="GroceryListItemTemplate"/>
</phone:LongListSelector.ItemTemplate>
</phone:LongListSelector>
這裏是我的MVVM代碼我有
public class GroceryItemsVm : ViewModelBase
{
public GroceryItemsVm()
{
if (IsInDesignMode)
{
}
else
{
EditGroceryItemCmd = new RelayCommand<GroceryItem>(this.Edit);
DeleteGroceryItemCmd = new RelayCommand<GroceryItem>(this.Delete);
GroceryItems = // method that gets all items back as grouped.
}
}
private List<Group<GroceryItem>> groceryItems = null;
/// <summary>
/// Sets and gets the GroceryItems property.
/// Changes to that property's value raise the PropertyChanged event.
/// </summary>
public List<Group<GroceryItem>> GroceryItems
{
get
{
return groceryItems;
}
set
{
if (groceryItems == value)
{
return;
}
RaisePropertyChanging(() => GroceryItems);
groceryItems = value;
RaisePropertyChanged(() => GroceryItems);
}
}
private async void Delete(GroceryItem obj)
{
// trigged on context delete
}
private void Edit(GroceryItem obj)
{
// triggered on context edit
}
public RelayCommand<GroceryItem> EditGroceryItemCmd
{
get;
private set;
}
public RelayCommand<GroceryItem> DeleteGroceryItemCmd
{
get;
private set;
}
}
public class GroceryItem : ObservableObject
{
/// <summary>
/// The <see cref="Name" /> property's name.
/// </summary>
public const string NamePropertyName = "Name";
private string name = "";
/// <summary>
/// Sets and gets the Name property.
/// Changes to that property's value raise the PropertyChanged event.
/// </summary>
public string Name
{
get
{
return name;
}
set
{
if (name == value)
{
return;
}
RaisePropertyChanging(() => Name);
name = value;
RaisePropertyChanged(() => Name);
}
}
}
現在,當我運行它時,它第一次工作,無論我選擇編輯它的項目,都會爲它獲取正確的對象。然而,下一個對象將始終是相同的。選擇完成後,它決不會改變它的選擇。
編輯
下面是一個例子。
- 運行它
- 觸發上下文菜單顯示在 「1」
- 命中編輯 - 注意對話消息(會說1)
- 命中 「返回鍵」
- 觸發上下文菜單以顯示「3」
- 點擊編輯 - 註釋對話框消息(將會顯示3)
我能想到的唯一的事情就是覆蓋我要去的頁面的後退按鈕,並且只需導航到頁面即可。這是有點愚蠢,但這是我能想到的。
public partial class MvvmView1 : PhoneApplicationPage
{
// Constructor
public MvvmView1()
{
InitializeComponent();
// Sample code to localize the ApplicationBar
//BuildLocalizedApplicationBar();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
NavigationService.GoBack();
}
protected override void OnBackKeyPress(CancelEventArgs e)
{
NavigationService.Navigate(new Uri("/MainPage.xaml", UriKind.Relative));
}
}
GroceryItemsVm.EditGroceryItemCmd?爲什麼不是GroceryItemViewModel的根目錄中的命令?如果你這樣做,你不需要使用長路徑,只需{綁定編輯}。 –
它如何知道如果它位於根目錄下,它需要發送給視圖模型的是哪個Grocery Item?長列表選擇器中的每個Grocery Item實質上都需要它自己的上下文菜單,因此它知道正在編輯哪一行。 – chobo2
您的ContextMenu綁定到屬性'GroceryItemsVm'。這個屬性在哪裏?請記住,命令的綁定與常規綁定沒有區別。如果'EditGroceryItemCmd'與'Name'和'ProductInfoLabel'存在於同一個類中,那麼您需要刪除用於命令綁定的'GroceryItemsVm'前綴 –