列表框不选择所选项目 [英] ListBox Not Selecting the Selected Item

查看:185
本文介绍了列表框不选择所选项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请参阅下面
code Visual Studio 2010中
上面的列表框有一个文本框。
通过绑定的文本框,当选择了一个项目能获得更大或更小。
这会导致列表框移动。
当ListBox中移动选定的项目不被点击的项目。
选择的项目是在鼠标的移动ListBox中的项目。
有时候它甚至不会选择在所有(尝试从9到10或10比9)。
在这种code甚至重现问题和奇数产生不同的长度。
所以,如果你奇怪,奇数或偶数连那就没问题去了。
如果从在奇数走在顶部甚至在底部(无滚动)则有时甚至没有被考虑将被选择的项目。
在C文本框的真正$ C $是项目的说明和描述是不同的长度。
有趣的是在调试并有上拿到一个破发点{返回boundText; }然后它选择合适的项目。
我认为它处理的选择,然后测量出用户界面,然后处理选择第二次对新的用户界面。
由于它的行为在调试不同,很难搞清楚。

 <窗​​口x:类=ListBoxMissClick.MainWindow
        的xmlns =htt​​p://schemas.microsoft.com/winfx/2006/xaml/$p$psentation
        的xmlns:X =htt​​p://schemas.microsoft.com/winfx/2006/xaml
        标题=主窗口高度=350宽度=525
        的DataContext ={绑定的RelativeSource = {的RelativeSource自}}>
    <电网>
        < Grid.RowDefinitions>
            < RowDefinition高度=自动/>
            < RowDefinition身高=*/>
        < /Grid.RowDefinitions>
        < Grid.ColumnDefinitions>
            &所述; ColumnDefinition宽度=*/>
        < /Grid.ColumnDefinitions>
        <文本框Grid.Row =0Grid.Column =0文本={绑定路径= BoundText}TextWrapping =自动换行/>
        <列表框Grid.Row =1Grid.Column =0的ItemsSource ={绑定路径= BoundList}的SelectedItem ={绑定路径= BoundListSelected,模式=双向}/>
    < /网格>
< /窗>

使用System.ComponentModel;

命名空间ListBoxMissClick
{
    ///<总结>
    ///为MainWindow.xaml交互逻辑
    ///< /总结>
    公共部分类主窗口:窗口,INotifyPropertyChanged的
    {
        私人字符串boundListSelected;
        私人字符串boundText =的String.Empty;
        私人列表<字符串> boundList =新的名单,其中,串>();
        私人布尔shortLong = TRUE;
        公共事件PropertyChangedEventHandler的PropertyChanged;

        保护无效NotifyPropertyChanged(字符串信息)
        {
            如果(的PropertyChanged!= NULL)
            {
                的PropertyChanged(这一点,新PropertyChangedEventArgs(信息));
            }
        }

        公共主窗口()
        {
            的for(int i = 0; I< 1000;我++)
            {
                boundList.Add(i.ToString());
            }

            的InitializeComponent();

        }
        公共字符串BoundText
        {
            {返回boundText; }
            组
            {
                如果(boundText!=值)
                {
                    boundText =价值;
                    NotifyPropertyChanged(BoundText);
                }
            }
        }
        公开名单<字符串> BoundList {{返回boundList; }}
        公共字符串BoundListSelected
        {
            {返回boundListSelected; }
            组
            {
                boundListSelected =价值;
                如果(Int32.Parse(值)%2 == 0)
                {
                    BoundText = value.ToString()+的东西很长的东西很长的东西很长的东西很长的东西很长的东西很长的东西很长的东西很长的东西很长的东西很longsomething很长的东西很长的东西很长的东西很长东西很longsomething很长的东西很长的东西很长的东西很长的东西很longsomething很长的东西很长的东西很长的东西很长的东西很longsomething很长的东西很长的东西很长的东西很长的东西很长;
                }
                其他
                {
                    BoundText = value.ToString()+的东西短;
                }
             }
        }

        私人无效ListBox_MouseDoubleClick(对象发件人,MouseButtonEventArgs E)
        {
            BoundText =的东西很长的东西很长的东西很长的东西很长的东西很长的东西很长的东西很长的东西很长的东西很长的东西很longsomething很长的东西很长的东西很长的东西很长的东西很longsomething很长的东西很长的东西很长的东西很长的东西很longsomething很长的东西很长的东西很长的东西很长的东西很longsomething很长的东西很长的东西很长的东西很长的东西很长;
        }
    }
}
 

在除了接受的答案Mouse.Capture和ReleaseMouseCapture工作

 集
{
    Mouse.Capture(本);
    {
        boundListSelected =价值;
        如果(Int32.Parse(值)%2 == 0)
        {
            BoundText = value.ToString()+的东西很长的东西很长的东西很长的东西很长的东西很长的东西很长的东西很长的东西很长的东西很长的东西很longsomething很长的东西很长的东西很长的东西很长东西很longsomething很长的东西很长的东西很长的东西很长的东西很longsomething很长的东西很长的东西很长的东西很长的东西很longsomething很长的东西很长的东西很长的东西很长的东西很长;
        }
        其他
        {
            BoundText = value.ToString()+的东西短;
        }
    }
    ReleaseMouseCapture();
}
 

解决方案

我已经重写你的codeA位。诀窍是使用MouseCapture,以避免多重事件处理(与原来的code,列表框正在上三个选择为一个单一的点击,由于布局量变到质变,而鼠标按键pressed)

下面是code:

MainWindow.xaml

 <窗​​口的xmlns =htt​​p://schemas.microsoft.com/winfx/2006/xaml/$p$psentation
        的xmlns:X =htt​​p://schemas.microsoft.com/winfx/2006/xaml
        X:类=TextEditor.MainWindow
        标题=主窗口高度=350宽度=525>

    <电网>
        < Grid.RowDefinitions>
            < RowDefinition高度=自动/>
            < RowDefinition身高=*/>
        < /Grid.RowDefinitions>
        <文本框Grid.Row =0文本={绑定路径= BoundText}TextWrapping =自动换行/>
        &所述;列表框Grid.Row =1
                 的ItemsSource ={绑定路径= BoundList}
                 的SelectedItem ={绑定路径= BoundListSelected,模式=双向}/>
    < /网格>

< /窗>
 

MainWindow.xaml.cs

 使用系统;
使用System.Collections.Generic;
使用System.Windows;
使用System.Windows.Input;

命名空间文本编辑
{
    ///<总结>
    ///为MainWindow.xaml交互逻辑
    ///< /总结>
    公共部分类主窗口:窗口
    {
        公共字符串BoundText
        {
            {返回(串)的GetValue(BoundTextProperty); }
            集合{的SetValue(BoundTextProperty,价值); }
        }

        //使用的DependencyProperty作为后备存储BoundText。这使得动画制作,造型,绑定等..
        公共静态只读的DependencyProperty BoundTextProperty =
            DependencyProperty.Register(BoundText的typeof(串)的typeof(主窗口),新PropertyMetadata(的String.Empty));

        公共字符串BoundListSelected
        {
            {返回(串)的GetValue(BoundListSelectedProperty); }
            集合{的SetValue(BoundListSelectedProperty,价值); }
        }

        //使用的DependencyProperty作为后备存储BoundListSelected。这使得动画制作,造型,绑定等..
        公共静态只读的DependencyProperty BoundListSelectedProperty =
            DependencyProperty.Register(BoundListSelected的typeof(串)的typeof(主窗口),新PropertyMetadata(的String.Empty,OnBoundListSelectedChanged));

        私有静态无效OnBoundListSelectedChanged(DependencyObject的研发,DependencyPropertyChangedEventArgs E)
        {
            VAR的主窗口= D作为主窗口;
            VAR值= e.NewValue为字符串;

            Mouse.Capture(的主窗口);

            如果(Int32.Parse(值)%2 == 0)
            {
                mainWindow.BoundText = value.ToString()+的东西很长的东西很长的东西很长的东西很长的东西很长的东西很长的东西很长的东西很长的东西很长的东西很longsomething很长的东西很长的东西很长的东西很长的东西很longsomething很长的东西很长的东西很长的东西很长的东西很longsomething很长的东西很长的东西很长的东西很长的东西很longsomething很长的东西很长的东西很长的东西很长的东西很长;
            }
            其他
            {
                mainWindow.BoundText = value.ToString()+的东西短;
            }

            mainWindow.ReleaseMouseCapture();
        }

        公共主窗口()
        {
            的for(int i = 0; I< 1000;我++)
            {
                boundList.Add(i.ToString());
            }

            的InitializeComponent();
            的DataContext =这一点;
        }

        公开名单<字符串> BoundList {{返回boundList; }}
        私人列表<字符串> boundList =新的名单,其中,串>();
    }
}
 

编辑:其实,我改变了主窗口的方式是codeD(也没有必要实现INotifyPropertyChanged在DependencyObject的,所以我只是删除,并设置两个依赖属性),但你可以尝试解决您的问题,您ogirinal code。通过简单的捕捉鼠标设置BoundText,然后释放它。

See code below
Visual Studio 2010
Above the ListBox have a TextBox.
Via binding the TextBox can get bigger or smaller when an item is selected.
That causes the ListBox to move.
When the ListBox moves the selected item is NOT the item that was clicked.
The selected item is the item under the mouse on the moved ListBox.
Some times it will not even select at all (try and go from 9 to 10 or from 10 to 9).
In this code to reproduce the problem even and odd produce different lengths.
So if you go from odd to odd or even to even then no problem.
If you go from on odd at the top an even at the bottom (without scrolling) then sometimes an item that was not even in view will be selected.
In the real code the TextBox is a description of the item and the descriptions are different lengths.
Interesting is in debug and there is a break point on get { return boundText; } then it does select the proper item.
I think it processes the select, then measures out the UI, and then processes the select a second time on the new UI.
Since it behaves different in debug it is hard to figure out.

<Window x:Class="ListBoxMissClick.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525"
        DataContext="{Binding RelativeSource={RelativeSource Self}}">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <TextBox Grid.Row="0" Grid.Column="0" Text="{Binding Path=BoundText}" TextWrapping="Wrap" />
        <ListBox Grid.Row="1" Grid.Column="0" ItemsSource="{Binding Path=BoundList}" SelectedItem="{Binding Path=BoundListSelected, Mode=TwoWay}"/>
    </Grid>
</Window>

using System.ComponentModel;

namespace ListBoxMissClick
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window, INotifyPropertyChanged
    {
        private string boundListSelected;
        private string boundText = string.Empty;
        private List<string> boundList = new List<string>();
        private bool shortLong = true;
        public event PropertyChangedEventHandler PropertyChanged;

        protected void NotifyPropertyChanged(String info)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(info));
            }
        }

        public MainWindow()
        {
            for (int i = 0; i < 1000; i++)
            {
                boundList.Add(i.ToString());
            }

            InitializeComponent();

        }
        public string BoundText 
        { 
            get { return boundText; }
            set 
            { 
                if (boundText != value)
                {
                    boundText = value;
                    NotifyPropertyChanged("BoundText");
                }
            }
        }
        public List<string> BoundList { get { return boundList; } }
        public string BoundListSelected
        {
            get { return boundListSelected; }
            set
            {
                boundListSelected = value;
                if (Int32.Parse(value) % 2 == 0)
                {
                    BoundText = value.ToString() + " something very long something very long something very long something very long something very long something very long something very long something very long something very long something very longsomething very long something very long something very long something very long something very longsomething very long something very long something very long something very long something very longsomething very long something very long something very long something very long something very longsomething very long something very long something very long something very long something very long";
                }
                else
                {
                    BoundText = value.ToString() + " something short "; 
                }
             }
        }

        private void ListBox_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            BoundText = " something very long something very long something very long something very long something very long something very long something very long something very long something very long something very longsomething very long something very long something very long something very long something very longsomething very long something very long something very long something very long something very longsomething very long something very long something very long something very long something very longsomething very long something very long something very long something very long something very long";
        }
    }
}

In addition to the accepted answer Mouse.Capture and ReleaseMouseCapture work.

set
{
    Mouse.Capture(this);
    {
        boundListSelected = value;
        if (Int32.Parse(value) % 2 == 0)
        {
            BoundText = value.ToString() + " something very long something very long something very long something very long something very long something very long something very long something very long something very long something very longsomething very long something very long something very long something very long something very longsomething very long something very long something very long something very long something very longsomething very long something very long something very long something very long something very longsomething very long something very long something very long something very long something very long";
        }
        else
        {
            BoundText = value.ToString() + " something short ";
        }
    }
    ReleaseMouseCapture();
}

解决方案

I've rewritten your code a bit. The trick is to use a MouseCapture to avoid having multiple event handling (with your original code, the listBox was getting up to three selection for a single click due to the layout changeing while mouse button was pressed)

Here is the code :

MainWindow.xaml

<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        x:Class="TextEditor.MainWindow"
        Title="MainWindow" Height="350" Width="525">

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <TextBox Grid.Row="0" Text="{Binding Path=BoundText}" TextWrapping="Wrap" />
        <ListBox Grid.Row="1" 
                 ItemsSource="{Binding Path=BoundList}" 
                 SelectedItem="{Binding Path=BoundListSelected, Mode=TwoWay}"/>
    </Grid>

</Window>

MainWindow.xaml.cs

using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Input;

namespace TextEditor
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public string BoundText
        {
            get { return (string)GetValue(BoundTextProperty); }
            set { SetValue(BoundTextProperty, value); }
        }

        // Using a DependencyProperty as the backing store for BoundText.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty BoundTextProperty =
            DependencyProperty.Register("BoundText", typeof(string), typeof(MainWindow), new PropertyMetadata(string.Empty));

        public string BoundListSelected
        {
            get { return (string)GetValue(BoundListSelectedProperty); }
            set { SetValue(BoundListSelectedProperty, value); }
        }

        // Using a DependencyProperty as the backing store for BoundListSelected.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty BoundListSelectedProperty =
            DependencyProperty.Register("BoundListSelected", typeof(string), typeof(MainWindow), new PropertyMetadata(string.Empty, OnBoundListSelectedChanged));

        private static void OnBoundListSelectedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var mainWindow = d as MainWindow;
            var value = e.NewValue as string;

            Mouse.Capture(mainWindow);

            if (Int32.Parse(value) % 2 == 0)
            {
                mainWindow.BoundText = value.ToString() + " something very long something very long something very long something very long something very long something very long something very long something very long something very long something very longsomething very long something very long something very long something very long something very longsomething very long something very long something very long something very long something very longsomething very long something very long something very long something very long something very longsomething very long something very long something very long something very long something very long";
            }
            else
            {
                mainWindow.BoundText = value.ToString() + " something short ";
            }

            mainWindow.ReleaseMouseCapture();
        }

        public MainWindow()
        {
            for (int i = 0; i < 1000; i++)
            {
                boundList.Add(i.ToString());
            }

            InitializeComponent();
            DataContext = this;
        }

        public List<string> BoundList { get { return boundList; } }
        private List<string> boundList = new List<string>();
    }
}

Edit : I actually changed the way MainWindow was coded (it's not necessary to implement INotifyPropertyChanged on a DependencyObject, so i just removed it and set two dependency properties) but you could try solving your issue with your ogirinal code by simply capturing the mouse before setting BoundText, and then releasing it.

这篇关于列表框不选择所选项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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