简体   繁体   English

WPF mvvm绑定,获取/设置值:阻止更新值的问题

[英]WPF mvvm binding, get/set value: issue with preventing update value

I'm working in a WPF mvvm environment. 我正在WPF mvvm环境中工作。

I have some binded vars and data from cs file to xaml. 我从CS文件到xaml有一些绑定的var和数据。

One is different from others: it is the index of the selected tab in my tabsCollection. 一个不同于其他:它是我的tabsCollection中所选标签的索引。 When the user has more than one tab opened and has got mods to save, I show him a dialog. 当用户打开多个标签并保存了mod时,我将向他显示一个对话框。 If he cliks "ok", he proceed with the change of the tab, if he clicks "cancel", the tab must remain the same. 如果单击“确定”,则继续更改选项卡;如果单击“取消”,则选项卡必须保持不变。

this is my code: 这是我的代码:

private int p_SelectedDocumentIndex;
public int SelectedDocumentIndex{ get { return p_SelectedDocumentIndex; }
    set {
        if (tabsCollection.Count() > 1 && CanSave() == true)
        {
            if (dm.ShowMessage1(ServiceContainer.GetService<DevExpress.Mvvm.IDialogService>("confirmYesNo")))
            {
                p_SelectedDocumentIndex = value;
                base.RaisePropertiesChanged("SelectedDocumentIndex");
            }
            //else {
            //    CODE FOR NOT CHANGE THE VALUE 
            //}
        }
        else {
            p_SelectedDocumentIndex = value;
            base.RaisePropertiesChanged("SelectedDocumentIndex");
        }
    }
 }

So, the question is: how can I not apply the change in the "set" section? 因此,问题是:我如何不能在“设置”部分中应用更改? (like an undo, I think) (我认为就像撤消一样)

This is simpliest way to do it, but, if this approach is incorrect, how can I do? 这是最简单的方法,但是,如果此方法不正确,该怎么办?

Previous failed attempts: 先前失败的尝试:

1)
p_SelectedDocumentIndex = p_SelectedDocumentIndex
base.RaisePropertiesChanged("SelectedDocumentIndex");

2)
base.RaisePropertiesChanged("SelectedDocumentIndex");

3)
nothing in the else branch
Dispatcher.CurrentDispatcher.BeginInvoke(new Action(() => SelectedDocumentIndex= p_SelectedDocumentIndex ), DispatcherPriority.Send);

该调用安排将UI状态恢复到操作开始之前的状态

I solved it. 我解决了 I've took the solution from here: 我从这里获取解决方案:

http://blog.alner.net/archive/2010/04/25/cancelling-selection-change-in-a-bound-wpf-combo-box.aspx http://blog.alner.net/archive/2010/04/25/cancelling-selection-change-in-a-bound-wpf-combo-box.aspx

    public int SelectedDocumentIndex{ get { return p_SelectedDocumentIndex; }
        set {
            // Store the current value so that we can 
            // change it back if needed.
            var origValue = p_SelectedDocumentIndex;

            // If the value hasn't changed, don't do anything.
            if (value == p_SelectedDocumentIndex)
                return;

            // Note that we actually change the value for now.
            // This is necessary because WPF seems to query the 
            //  value after the change. The combo box
            // likes to know that the value did change.
            p_SelectedDocumentIndex = value;
            if (tabsCollection.Count() > 1 && CanSave() == true)
            {
                if (!dm.ShowMessage1(ServiceContainer.GetService<DevExpress.Mvvm.IDialogService>("confirmYesNo")))
                {
                    Debug.WriteLine("Selection Cancelled.");

                    // change the value back, but do so after the 
                    // UI has finished it's current context operation.
                    Application.Current.Dispatcher.BeginInvoke(
                            new Action(() =>
                            {
                                Debug.WriteLine("Dispatcher BeginInvoke " + "Setting CurrentPersonCancellable.");

                                // Do this against the underlying value so 
                                //  that we don't invoke the cancellation question again.
                                p_SelectedDocumentIndex = origValue;
                                DocumentPanel p = tabsCollection.ElementAt(p_SelectedDocumentIndex);
                                p.IsActive = true;
                                base.RaisePropertiesChanged("SelectedDocumentIndex");
                            }),
                            System.Windows.Threading.DispatcherPriority.ContextIdle,
                            null
                        );

                    // Exit early. 
                    return;
                }
            }
            // Normal path. Selection applied. 
            // Raise PropertyChanged on the field.
            Debug.WriteLine("Selection applied.");
            base.RaisePropertiesChanged("SelectedDocumentIndex");
        }
    }

If your VM class is derived from DependencyObject then you can change your property to a DependecyProperty with a coerce callback which enables "undo" as follows: 如果您的VM类是从DependencyObject派生的,则可以使用强制回调将属性更改为DependecyProperty ,该回调将启用“撤消”,如下所示:

    public int SelectedDocumentIndex
    {
        get { return (int)GetValue(SelectedDocumentIndexProperty); }
        set { SetValue(SelectedDocumentIndexProperty, value); }
    }
    public static readonly DependencyProperty SelectedDocumentIndexProperty =
        DependencyProperty.Register("SelectedDocumentIndex", typeof(int), typeof(MyViewModel), new PropertyMetadata(0,
            (d, e) =>
            {
                //Callback after value is changed
                var vm = (MyViewModel)d;
                var val = (int)e.NewValue;
            }, (d, v) =>
            {
                //Coerce before value is changed
                var vm = (MyViewModel)d;
                var val = (int)v;
                if (vm.tabsCollection.Count() > 1 && vm.CanSave() == true)
                {
                    if (vm.dm.ShowMessage1(ServiceContainer.GetService<DevExpress.Mvvm.IDialogService>("confirmYesNo")))
                    {
                        //no coerce is needed
                        return v;
                    }
                    else
                    {
                        //should coerce to the previous value
                        return VM.SelectedDocumentIndex;
                    }
                }
                else
                {
                    //no coerce is needed
                    return v;
                }
            }));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM