上下文菜单继续使用Mvvm获取错误的对象 [英] Context Menu Keep Getting Wrong Object using Mvvm

查看:81
本文介绍了上下文菜单继续使用Mvvm获取错误的对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在制作winodws 8电话应用程序,并尝试通过Windows Phone工具包在其上显示上下文菜单.

I am making a winodws 8 phone application and trying to have a context menu on it from the Windows Phone tool kit.

我一直在关注教程,但是而不是列表框,我使用的是WP8内置的长列表选择器

I been following this tutorial but instead of list box I am using a long list selector that is built into 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代码

Here is my mvvm code I have

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);
                }
            }
        }

现在,当我运行它时,它第一次起作用,无论我选择编辑它的哪个项目,都将为它找到合适的对象.但是,下一个对象将始终是相同的.选择完成后,它再也不会改变选择.

Now when I run it, It works for the first time, whatever item I choose to edit it, will get the right object for it. However the next object will always be the same. It never changes it choice after the selection is done.

修改

这里是一个例子.

https://onedrive .live.com/redir?resid = FAE864D71B4770C6!19080& authkey =!ACUC2xXmZLVD7fE& ithint = file%2c.zip

  1. 运行
  2. 触发上下文菜单以显示"1"以上
  3. 命中编辑-注释对话框消息(将显示1)
  4. 点击返回按钮"
  5. 触发上下文菜单以显示"3"以上
  6. 命中编辑-注释对话框消息(将显示3)

我唯一能想到的就是覆盖我要进入的页面的后退按钮,然后导航至该页面.这有点愚蠢,但这就是我能想到的.

The only thing I can think of is override the back button for the pages I am going to and just do a Navigate to the page. It is kinda stupid but that's all I can think off.

  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));
        }


    }

推荐答案

这是ContextMenu的常见问题.我已经尝试了一段时间,想出一个解决方案,四处寻找.您说过,单击一次永远不会正确.

This is common problem with ContextMenu. I have been trying for some time to think of a solution searching all around for something. You said after you click once it nevers gets it right.

请尝试以下操作:

将卸载的处理程序添加到您contextmenu中,如下所示:

Add the unloaded handler to you contextmenu as follows:

<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 ***Unloaded="ContextMenu_Unloaded"***>
            <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>

删除 * 我添加了它们以强调更改. 然后,该处理程序的代码如下:

Remove the * I added them to emphasize the changes. And then the code behind for that handler would be:

private void ContextMenu_Unloaded(object sender, RoutedEventArgs e)
{
    var conmen = (sender as ContextMenu);
    if (conmen != null)
        conmen.ClearValue(DataContextProperty);
}

让我知道这是否可行.

这篇关于上下文菜单继续使用Mvvm获取错误的对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆