【问题标题】:How to Set Index of ListPicker without Executing ValueChanged Event如何在不执行 ValueChanged 事件的情况下设置 ListPicker 的索引
【发布时间】:2014-11-09 16:05:50
【问题描述】:

这个问题一直把我逼疯了。我有一个用多个项目动态填充的 ListPicker。我已在页面的 Loaded 事件中声明了我的 SelectionChanged 事件处理程序。当用户单击页面上的某个项目时,ListPicker 的可见性将从 Collpased 切换为 Visible,并且我设置了 ListPicker 的值。问题是,ListPicker 的索引将基于用户设置,因此在三个项目中,当前索引可能是 1,而不是默认的 0。我需要将 1 显示为 ListPicker 中的当前项目,而不触发 SelectionChanged 事件(它根据当前索引执行操作)。然后,只有当用户自己更改所选项目时,我才需要触发 SelectionChanged 事件。

这样做的主要原因不仅是用户需要在 ListPicker 显示时查看他或她的当前设置,而且在 SelectionChanged 事件发生操作时会覆盖当前存在的内容,这非常令人困惑且不应该除非用户指定,否则发生。

我目前拥有的如下

XAML

<toolkit:ListPicker x:Name="lp" Visibility="Collapsed" Margin="12" Width="300"/>

XAML.CS

private void Page_Loaded(object sender, RoutedEventArgs e)
    {
        lp.SelectionChanged += lp_SelectionChanged;
    }

void EditableEllipse_Tap(object sender, System.Windows.Input.GestureEventArgs e)
{
    if (sender != null)
    {
        DependencyObject tappedElement = e.OriginalSource as UIElement;
        // find parent UI element of type PhotoThumbnail
        //PhotoThumbnail i = this.FindParentOfType<PhotoThumbnail>(tappedElement);
        i = this.FindParentOfType<PhotoThumbnail>(tappedElement);
        if (i != null)
        {
            BuildControl(i);
        }
    }
}

private void BuildControl(PhotoThumbnail pp)
    {
        switch(pp.NName)
        {
            case "flip":
                List<ListPickerItem> l = new List<ListPickerItem>();                    
                l.Add(new ListPickerItem { Name = "Flip_Vertical", Content = AppResources.App_Flip_Vertical });
                l.Add(new ListPickerItem { Name = "Flip_Horizontal", Content = AppResources.App_Flip_Horizontal });
                l.Add(new ListPickerItem { Name = "Flip_Both", Content = AppResources.App_Flip_Both });
                lp.ItemsSource = l;  //Code execution jumps from here to ValueChanged event immediately                  
                lp.Visibility = Visibility.Visible;
                lp.SelectedIndex = Settings.Flip.Value - 1;
                break;
        ..
        }
    }

private async void lp_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
            if (lp.SelectedIndex != -1) //always defaults to = 0
            {
                var item = (sender as ListPicker).SelectedItem;
                string name = ((ListPickerItem)item).Name;

                if (name != null)
                {
                        switch (name)
                        {
                            case "Flip_Vertical":
                                Settings.Flip.Value = 1;
                                ..perform process based on current Setting.Flip.Value..                                    break;
                            case "Flip_Horizontal":
                                Settings.Flip.Value = 2;
                                ..perform process based on current Setting.Flip.Value..
                                break;
                            case "Flip_Both":
                                Settings.Flip.Value = 3;
                                ..perform process based on current Setting.Flip.Value..
                                break;

                             ...
                          }
                }
            }

【问题讨论】:

    标签: c# xaml windows-phone-8 listpicker


    【解决方案1】:

    尝试使用顺序操作技术(通过取消挂钩和重新挂钩事件)

    private void BuildControl(PhotoThumbnail pp)
    {
        switch(pp.NName)
        {
            case "flip":
    
                // unhook event
                lp.SelectionChanged -= lp_SelectionChanged;
    
                List<ListPickerItem> l = new List<ListPickerItem>();                    
                l.Add(new ListPickerItem { Name = "Flip_Vertical", Content = AppResources.App_Flip_Vertical });
                l.Add(new ListPickerItem { Name = "Flip_Horizontal", Content = AppResources.App_Flip_Horizontal });
                l.Add(new ListPickerItem { Name = "Flip_Both", Content = AppResources.App_Flip_Both });
                lp.ItemsSource = l;  //Code execution jumps from here to ValueChanged event immediately                  
                lp.Visibility = Visibility.Visible;
                lp.SelectedIndex = Settings.Flip.Value - 1;
    
                // after setting the index, rehook the event
                lp.SelectionChanged += lp_SelectionChanged;
    
                break;
        ..
        }
    }
    

    【讨论】:

    • 有趣的是,在阅读本文作为最后的选择之前,我尝试了同样的事情并且它奏效了。你会建议从Page_Loaded 中删除lp.SelectionChanged += lp_SelectionChanged 吗?
    • @Matthew 这取决于您在 Page_Loaded 之后是否还有其他要触发的内容,如果没有,则可以安全地删除它。
    猜你喜欢
    • 2013-05-11
    • 1970-01-01
    • 2016-05-01
    • 1970-01-01
    • 2018-12-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-04
    相关资源
    最近更新 更多