不触发SelectionChanged事件设置ComboBox的选定值

5

我有一个ComboBox:

<ComboBox Name="drpRoute" SelectionChanged="drpRoute_SelectionChanged" />

我在代码后端设置了列表项:

public ClientReports()
{
    InitializeComponent();
    drpRoute.AddSelect(...listofcomboxitemshere....)
}


public static class ControlHelpers
{
    public static ComboBox AddSelect(this ComboBox comboBox, IList<ComboBoxItem> source)
    {
        source.Insert(0, new ComboBoxItem { Content = " - select - "});

        comboBox.ItemsSource = source;
        comboBox.SelectedIndex = 0;

        return comboBox;
    }
}

由于某些原因,当我设置SelectedIndex时,SelectionChanged事件会被触发。

我该如何在不触发SelectionChanged事件的情况下设置ItemSourceSelectedIndex

虽然我是WPF新手,但这似乎不应该像看起来的那么复杂,难道我漏掉了什么吗?


为什么您不希望触发“SelectionChanged”事件? - 123 456 789 0
我不确定我是否正确理解了你的问题,但是当选择索引更改时,“Selection Changed”触发似乎对我来说是合理的。如果您不希望在将索引设置为0时调用它,请在您的“SelectionChanged”处理程序中检查新索引,如果它为0,则退出而不执行其余的选择更改逻辑。 - Viv
我获取数据源,将下拉列表设置为默认的“选择”。之后用户可以选择一个项目,当他们选择时,SelectionChanged事件被触发,我会根据下拉列表的选择在页面上执行一系列操作。现在发生的是,当我设置原始数据源时,由于在加载时触发了SelectionChanged事件,所以选择逻辑被执行。 - stoic
1
在将SelectedIndex设置为0之前,先移除事件处理程序,然后在设置SelectedIndex后再重新附加它。类似于 comboBox.SelectionChanged -= drpRoute_SelectionChanged; comboBox.SelectedIndex = 0; comboBox.SelectionChanged += drpRoute_SelectionChanged; - Viv
@Viv 这对于一个简单的问题来说太丑了。 - 123 456 789 0
显示剩余3条评论
2个回答

10

SelectionChanged事件无论是通过代码还是用户交互设置,都会触发。为了避免这种情况,您需要在代码中更改处理程序时删除该处理程序,就像@Viv建议的那样,或者添加一个标志以在您在代码中更改它时忽略这些更改。第一种选项不会触发事件,因为您没有监听它,而在第二种选项中,您需要检查标志以查看它是否由代码更改触发。

更新: 以下是使用标志的示例:

bool codeTriggered = false;

// Where ever you set your selectedindex to 0
codeTriggered = true;
comboBox.SelectedIndex = 0;
codeTriggered = false;

// In your SelectionChanged event handler
if (!codeTriggered)
{
   // Do stuff when user initiated the selection changed
}

在代码中进行更改时,添加一个标志以忽略更改,但我不确定如何实现。 - stoic

4
你可以通过数据绑定来解决这个问题:
private int _sourceIndex;
public int SourceIndex
{
    get { return _sourceIndex; }
    set
    {
        _sourceIndex= value;
        NotifyPropertyChanged("SourceIndex");
    }
}

private List<ComboBoxItem> _sourceList;
public List<ComboBoxItem> SourceList
{
    get { return _sourceList; }
    set
    {
        _sourceList= value;
        NotifyPropertyChanged("SourceList");
    }
}

public ClientReports()
{
    InitializeComponent();

    // Set the DataContext
    DataContext = this;

    // set the sourceIndex to 0
    SourceIndex = 0;

    // SourceList initialization
    source = ... // get your comboboxitem list
    source.Insert(0, new ComboBoxItem { Content = " - select - "});
    SourceList = source
}

在XAML中绑定SelectedItem和ItemsSource。
<ComboBox Name="drpRoute" 
   ItemsSource="{Binding SourceList}"
   SelectedIndex="{Binding SourceIndex}" />

使用数据绑定,每次您在代码中更改SourceIndex时,它都会在UI中更改,在UI中更改它也会在类中更改。您可以尝试查找有关MVVM设计模式的教程,这是编写WPF应用程序的好方法。


这是解决问题的正确方法,因为像其他答案所指出的那样,不可能删除SelectionChanged事件。 - BradleyDotNET
这个项目没有实现MVVM,它只是一个小的单页应用程序 :( - stoic
我写的例子并不是真正的MVVM(MVVM应该有一个ModelView作为数据上下文),而只是一些简单的数据绑定,你可以使用它来解决这个特定的问题,并在工作正常时使用事件。 - Aurelien Souchet
1
@LordTakkera 我不建议删除 SelectionChanged 事件,而是删除事件处理程序。实际上,你可以删除事件处理程序。 - evanb
@evanb 我完全同意。谢谢你的澄清。 - BradleyDotNET
"如果您在UI中更改它,它也会在类中更改":如果绑定中不使用Mode=TwoWay,则不行。 - Cabuxa.Mapache

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接