取消组合框选择在WPF与MVVM [英] Cancel combobox selection in WPF with MVVM

查看:141
本文介绍了取消组合框选择在WPF与MVVM的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个组合框在我的WPF应用程序:

I've got a combobox in my WPF application:

<ComboBox  ItemsSource="{Binding CompetitorBrands}" DisplayMemberPath="Value" 
   SelectedValuePath="Key" SelectedValue="{Binding Path=CompMfgBrandID, Mode=TwoWay,
   UpdateSourceTrigger=PropertyChanged}" Text="{Binding CompMFGText}"/>

绑定到集合 KeyValuePair&LT;字符串,字符串&GT;

下面是我的ViewModel的CompMfgBrandID属性:

Here is the CompMfgBrandID property in my ViewModel:

public string CompMfgBrandID
{
    get { return _compMFG; }
    set
    {    
        if (StockToExchange != null && StockToExchange.Where(x => !string.IsNullOrEmpty(x.EnteredPartNumber)).Count() > 0)
        {
            var dr = MessageBox.Show("Changing the competitor manufacturer will remove all entered parts from the transaction.  Proceed?",
                "Transaction Type", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
            if (dr != DialogResult.Yes)
                return;
        }

        _compMFG = value;
        StockToExchange.Clear();

        ...a bunch of other functions that don't get called when you click 'No'...
        OnPropertyChanged("CompMfgBrandID");
    }
}

如果您选择是,其行为符合市场预期。项目被清除,其余的函数被调用。如果让我选择否,则返回,并且不清除我的列表或调用任何其它功能,这是很好的,但组合框仍显示新的选择。我需要它恢复到原来的选区,仿佛什么都没有发生变化,当用户挑选否。我怎样才能做到这一点?我也尝试添加 e.Handled = TRUE 在codebehind,都无济于事。

If you choose "yes", it behaves as expected. Items are cleared and the remaining functions are called. If I choose 'No', it returns and doesn't clear my list or call any of the other functions, which is good, but the combobox still displays the new selection. I need it to revert back to the original selection, as if nothing had changed, when the user picks 'No'. How can I accomplish this? I also tried adding e.Handled = true in codebehind, to no avail.

推荐答案

要MVVM下做到这一点....

To achieve this under MVVM....

1]有一个附加的行为处理ComboBox的的SelectionChanged 事件。引发此事件与具有处理的标记某些事件参数。但它设置为true是无用的的SelectedValue 绑定。绑定更新源不论该事件是否已被处理。

1] Have an attached behavior that handles the SelectionChanged event of the ComboBox. This event is raised with some event args that have Handled flag. But setting it to true is useless for SelectedValue binding. The binding updates source irrespective of whether the event was handled.

2]因此,我们配置 ComboBox.SelectedValue 绑定为双向明确

2] Hence we configure the ComboBox.SelectedValue binding to be TwoWay and Explicit.

3]只有当您的检查是满意,消息框说是,当我们执行 BindingEx pression .UpdateSource()。否则,我们只需调用 BindingEx pression.UpdateTarget()来恢复旧的选择。

3] Only when your check is satisfied and messagebox says Yes is when we perform BindingExpression.UpdateSource(). Otherwise we simply call the BindingExpression.UpdateTarget() to revert to the old selection.

在我下面的例子中,我有 KeyValuePair℃的名单; INT,INT&GT; 绑定到窗口的数据上下文。在 ComboBox.SelectedValue 绑定到一个简单的写的myKey 窗口属性

In my example below, I have a list of KeyValuePair<int, int> bound to the data context of the window. The ComboBox.SelectedValue is bound to a simple writeable MyKey property of the Window.

XAML ...

    <ComboBox ItemsSource="{Binding}"
              DisplayMemberPath="Value"
              SelectedValuePath="Key"
              SelectedValue="{Binding MyKey,
                                      ElementName=MyDGSampleWindow,
                                      Mode=TwoWay,
                                      UpdateSourceTrigger=Explicit}"
              local:MyAttachedBehavior.ConfirmationValueBinding="True">
    </ComboBox>

其中, MyDGSampleWindow 是x:名称的窗口

code背后...

public partial class Window1 : Window
{
    private List<KeyValuePair<int, int>> list1;

    public int MyKey
    {
        get; set;
    }

    public Window1()
    {
        InitializeComponent();

        list1 = new List<KeyValuePair<int, int>>();
        var random = new Random();
        for (int i = 0; i < 50; i++)
        {
            list1.Add(new KeyValuePair<int, int>(i, random.Next(300)));
        }

        this.DataContext = list1;
    }
 }

以及附加的行为

And the attached behavior

public static class MyAttachedBehavior
{
    public static readonly DependencyProperty
        ConfirmationValueBindingProperty
            = DependencyProperty.RegisterAttached(
                "ConfirmationValueBinding",
                typeof(bool),
                typeof(MyAttachedBehavior),
                new PropertyMetadata(
                    false,
                    OnConfirmationValueBindingChanged));

    public static bool GetConfirmationValueBinding
        (DependencyObject depObj)
    {
        return (bool) depObj.GetValue(
                        ConfirmationValueBindingProperty);
    }

    public static void SetConfirmationValueBinding
        (DependencyObject depObj,
        bool value)
    {
        depObj.SetValue(
            ConfirmationValueBindingProperty,
            value);
    }

    private static void OnConfirmationValueBindingChanged
        (DependencyObject depObj,
        DependencyPropertyChangedEventArgs e)
    {
        var comboBox = depObj as ComboBox;
        if (comboBox != null && (bool)e.NewValue)
        {
            comboBox.Tag = false;
            comboBox.SelectionChanged -= ComboBox_SelectionChanged;
            comboBox.SelectionChanged += ComboBox_SelectionChanged;
        }
    }

    private static void ComboBox_SelectionChanged(
        object sender, SelectionChangedEventArgs e)
    {
        var comboBox = sender as ComboBox;
        if (comboBox != null && !(bool)comboBox.Tag)
        {
            var bndExp
                = comboBox.GetBindingExpression(
                    Selector.SelectedValueProperty);

            var currentItem
                = (KeyValuePair<int, int>) comboBox.SelectedItem;

            if (currentItem.Key >= 1 && currentItem.Key <= 4
                && bndExp != null)
            {
                var dr
                    = MessageBox.Show(
                        "Want to select a Key of between 1 and 4?",
                        "Please Confirm.",
                        MessageBoxButton.YesNo,
                        MessageBoxImage.Warning);
                if (dr == MessageBoxResult.Yes)
                {
                    bndExp.UpdateSource();
                }
                else
                {
                    comboBox.Tag = true;
                    bndExp.UpdateTarget();
                    comboBox.Tag = false;
                }
            }
        }
    }
}

在我使用的行为 ComboBox.Tag 属性来临时存储跳过当我们恢复到旧选定值的复检的标志。

In the behavior I use ComboBox.Tag property to temporarily store a flag that skips the rechecking when we revert back to the old selected value.

让我知道,如果这有助于。

Let me know if this helps.

这篇关于取消组合框选择在WPF与MVVM的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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