4

好的,这一定是一个重复的问题,但我找不到答案:我有一个数据绑定到集合的列表框。默认选择 Items[0]。如何防止这种情况发生,以确保在单击 ListBoxItem 时引发 SelectionChanged 事件?

编辑:我已经取消了 SelectedIndex=-1 路由,但我再次尝试:在 Listbox 的构造函数中(或作为 XAML 中的属性)将 SelectedIndex 设置为 -1 不起作用。似乎在初始化后填充了列表框,并且 selectedindex 最终将变为 0。将 SelectedItem 设置为 null 的情况相同;

我试过这个:

<ListBox ItemsSource="{Binding Value}" 
         SelectionChanged="ListBox_SelectionChanged"
         IsSynchronizedWithCurrentItem="True"
         Loaded="ListBox_Loaded">
</ListBox>

和:

 private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        if(e.AddedItems.Count==0)return;//Prevents stackoverflow! ;-)
        ((ListBox)e.OriginalSource).SelectedItem=null;
    }

private void ListBox_Loaded(object sender, RoutedEventArgs e)
{
    ((ListBox) sender).SelectedItem = null;
}

这可行,但是它在列表框显示的项目顶部插入了一个空行,这非常难看....在我的特殊情况下,我可以通过删除 IsSynchronizedWithCurrentItem 属性来解决问题。

但我可以想到很多情况下这是不可接受的。

上面的陈述是无稽之谈:要么您想使用主从绑定并将 IsSynchronizedWithCurrentItem 设置为 true,要么您不这样做。您不太可能想要使用主从绑定,然后在您的列表框中一直没有当前选定的项目

4

7 回答 7

6

运行一些测试后,ListBox 的默认行为是不预先选择列表中的项目。删除 IsSynchronizedWithCurrentItem="True" 将确保列表框不会开始预先选择,并且当用户单击任何项​​目时将引发 SelectionChanged 事件。

如果确实将 IsSynchronizedWithCurrentItem 设置为 true,则表示 selectedIndex 将始终等于 ListBox.Items 的 ListBox.Items.CurrentItem 的索引。ListBox.Items 始终具有 CurrentItem,并且由于 CurrentItem 或 CurrentIndex 为只读,因此无法设置为 -1 或 null。

希望对J有帮助

编辑...刚刚阅读

“在我的特殊情况下,我可以通过删除 IsSynchronizedWithCurrentItem 属性来解决问题。但我可以想到很多情况下这是不可接受的。”

在这种情况下,由于上述原因,我认为这是不可能的。

于 2009-11-29T18:41:09.597 回答
2
listbox.selectedIndex = -1

那应该取消选择所有内容(因为索引 -1 不存在),但据我所知,除非您明确设置默认 selectedItem 列表视图生成时没有选择任何内容,因此 SelectedIndex 可能被无意设置为一点。请注意,SelectedIndex 也可以在 XAML 中设置。

于 2009-11-24T14:42:36.040 回答
2

使用 CollectionView 作为列表框的 ItemsSource。一个新的 WPF 项目,最初没有选择任何项目:

XAML:

<Window x:Class="ListBoxDataBinding.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Grid>
    <ListBox 
        ItemsSource="{Binding Path=Value, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}" 
        SelectionChanged="ListBox_SelectionChanged"
        IsSynchronizedWithCurrentItem="True"
        >
    </ListBox>
</Grid>
</Window>

CS:

public partial class Window1: Window {
    public IEnumerable Value {
        get { return (IEnumerable)GetValue(ValueProperty); }
        set { SetValue(ValueProperty, value); }
    }

    public static readonly DependencyProperty ValueProperty =
        DependencyProperty.Register("Value", typeof(IEnumerable), typeof(Window1), new UIPropertyMetadata(null));


    public Window1() {
        InitializeComponent();
        var view = new TheCollectionView();
        view.MoveCurrentTo(null);
        this.Value = view;
    }

    private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e) {
        MessageBox.Show("Selection changed");
    }
}

public class TheCollectionView: CollectionView {
    public TheCollectionView(): base(new TheCollection()) {
    }
}

public class TheCollection: List<string> {
    public TheCollection() {
        Add("string1");
        Add("string2");
        Add("string3");
    }
}
于 2009-11-29T18:58:09.247 回答
1

您需要将索引设置为 -1,这告诉列表框不要选择任何内容。在 SelectionChanged 事件中,将列表框的 Index 属性设置为 -1。

希望这会有所帮助,最好的问候,汤姆。

于 2009-11-24T14:36:18.830 回答
1

如何转储 SelectionChanged 事件处理程序和数据绑定依赖属性或通知属性到 SelectedValue 呢?

于 2009-11-27T00:11:35.077 回答
1

只需转到列表框的属性。选择数据选项卡,然后选择绑定列。输入 -1 此项将自动更改为 65535。

接下来将 Allow Value List Edits 属性更改为 No。最后将 Locked 属性更改为 No。

现在您的用户无法选择列表中的项目,并且避免了项目上的反向视频。

于 2020-07-14T16:11:14.587 回答
0

You can use the Tap event instead of SelectionChanged:

<ListBox  ItemsSource="{Binding Data}" Tap="ListBox_Tap" ... />
于 2013-06-20T16:17:54.197 回答