Annuler la sélection combobox dans WPF avec MVVM

j'ai un combobox dans mon application WPF:

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

lié à une collection de KeyValuePair<string, string>

Voici la propriété CompMfgBrandID dans mon 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");
    }
}

Si vous choisissez "oui", il se comporte comme prévu. Les éléments sont effacés et les fonctions restantes sont appelées. Si je choisis "non", il retourne et ne nettoie pas ma liste ou n'appelle aucune des autres fonctions, ce qui est bien, mais le combobox reste affiche la nouvelle sélection. J'en ai besoin pour revenir à la sélection d'origine, comme si rien n'avait changé, lorsque l'utilisateur sélectionne "Non". Comment puis-je accomplir? J'ai aussi essayé d'ajouter e.Handled = true dans codebehind, en vain.

25
demandé sur BoltClock 2011-10-18 01:52:33

11 réponses

pour atteindre cet objectif dans le cadre du MVVM....

1] ont un comportement attaché qui gère l'événement SelectionChanged du ComboBox. Cet événement est soulevé avec quelques args d'événement qui ont Handled drapeau. Mais le mettre à true est inutile pour SelectedValue reliure. La source des mises à jour obligatoires, que l'événement ait été traité ou non.

2] Nous configurons donc la liaison ComboBox.SelectedValue à TwoWay et Explicit .

3] seulement quand votre check est satisfait et messagebox dit Yes est quand nous effectuons BindingExpression.UpdateSource() . Sinon, nous appelons simplement le BindingExpression.UpdateTarget() pour revenir à l'ancienne sélection.


Dans mon exemple ci-dessous, j'ai une liste de KeyValuePair<int, int> lié au contexte de données de la fenêtre. Le ComboBox.SelectedValue est lié à un simple MyKey propriété du Window .

XAML ...

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

MyDGSampleWindow est le x:Nom du Window .

Code Derrière ...

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;
    }
 }

Et le comportement attaché à

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;
                }
            }
        }
    }
}

dans le comportement que j'utilise ComboBox.Tag propriété pour stocker temporairement un drapeau qui saute la rechecking quand on revenir à l'ancienne valeur sélectionnée.

dites-moi si cela peut aider.

16
répondu WPF-it 2011-10-18 09:16:51

cela peut être réalisé de manière générique et compacte en utilisant le comportement Générique de Blend .

le comportement définit une propriété de dépendance appelée SelectedItem , et vous devez mettre votre reliure dans cette propriété, au lieu de la propriété SelectedItem de ComboBox. Le comportement est en charge de transmettre les changements dans la propriété de dépendance au ComboBox (ou plus généralement, au sélecteur), et lorsque le sélecteur SelectedItem change, il tente de le céder à sa propre propriété SelectedItem . Si la tâche échoue (probablement parce que le setter VM proeprty lié a rejeté la tâche), le comportement met à jour le sélecteur SelectedItem avec la valeur courante de sa propriété SelectedItem .

pour toutes sortes de raisons, vous pouvez rencontrer des cas où la liste des éléments dans le sélecteur est effacée, et l'élément sélectionné devient null (voir cette question ). Vous n'avez généralement pas vous voulez que votre propriété VM devienne nulle dans ce cas. Pour cela, j'ai ajouté la propriété de dépendance IgnoreNullSelection, ce qui est vrai par défaut. Cela devrait résoudre un tel problème.

c'est la classe CancellableSelectionBehavior :

using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Interactivity;

namespace MySampleApp
{
    internal class CancellableSelectionBehavior : Behavior<Selector>
    {
        protected override void OnAttached()
        {
            base.OnAttached();
            AssociatedObject.SelectionChanged += OnSelectionChanged;
        }

        protected override void OnDetaching()
        {
            base.OnDetaching();
            AssociatedObject.SelectionChanged -= OnSelectionChanged;
        }

        public static readonly DependencyProperty SelectedItemProperty =
            DependencyProperty.Register("SelectedItem", typeof(object), typeof(CancellableSelectionBehavior),
                new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnSelectedItemChanged));

        public object SelectedItem
        {
            get { return GetValue(SelectedItemProperty); }
            set { SetValue(SelectedItemProperty, value); }
        }

        public static readonly DependencyProperty IgnoreNullSelectionProperty =
            DependencyProperty.Register("IgnoreNullSelection", typeof(bool), typeof(CancellableSelectionBehavior), new PropertyMetadata(true));

        /// <summary>
        /// Determines whether null selection (which usually occurs since the combobox is rebuilt or its list is refreshed) should be ignored.
        /// True by default.
        /// </summary>
        public bool IgnoreNullSelection
        {
            get { return (bool)GetValue(IgnoreNullSelectionProperty); }
            set { SetValue(IgnoreNullSelectionProperty, value); }
        }

        /// <summary>
        /// Called when the SelectedItem dependency property is changed.
        /// Updates the associated selector's SelectedItem with the new value.
        /// </summary>
        private static void OnSelectedItemChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var behavior = (CancellableSelectionBehavior)d;

            // OnSelectedItemChanged can be raised before AssociatedObject is assigned
            if (behavior.AssociatedObject == null)
            {
                System.Windows.Threading.Dispatcher.CurrentDispatcher.BeginInvoke(new Action(() =>
                {
                    var selector = behavior.AssociatedObject;
                    selector.SelectedValue = e.NewValue;
                }));
            }
            else
            {
                var selector = behavior.AssociatedObject;
                selector.SelectedValue = e.NewValue;
            }
        }

        /// <summary>
        /// Called when the associated selector's selection is changed.
        /// Tries to assign it to the <see cref="SelectedItem"/> property.
        /// If it fails, updates the selector's with  <see cref="SelectedItem"/> property's current value.
        /// </summary>
        private void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (IgnoreNullSelection && (e.AddedItems == null || e.AddedItems.Count == 0)) return;
            SelectedItem = AssociatedObject.SelectedItem;
            if (SelectedItem != AssociatedObject.SelectedItem)
            {
                AssociatedObject.SelectedItem = SelectedItem;
            }
        }
    }
}

C'est la façon de L'utiliser dans XAML:

<Window x:Class="MySampleApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="My Smaple App" Height="350" Width="525"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:local="clr-namespace:MySampleApp"
        xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
        mc:Ignorable="d"
        d:DataContext="{d:DesignInstance local:MainWindowViewModel}">
    <StackPanel>
        <ComboBox ItemsSource="{Binding Options}">
            <i:Interaction.Behaviors>
                <local:CancellableSelectionBehavior SelectedItem="{Binding Selected}" />
            </i:Interaction.Behaviors>
        </ComboBox>
    </StackPanel>
</Window>

et ceci est un échantillon de la propriété VM:

private string _selected;

public string Selected
{
    get { return _selected; }
    set
    {
        if (IsValidForSelection(value))
        {
            _selected = value;
        }
    }
}
17
répondu splintor 2017-05-23 12:26:24

solution très simple pour .NET 4.5.1+:

<ComboBox SelectedItem="{Binding SelectedItem, Delay=10}" ItemsSource="{Binding Items}"  />

Ça marche pour moi, dans la plupart des cas. Vous pouvez faire reculer la sélection dans combobox, juste le feu NotifyPropertyChanged sans assignation de valeur.

14
répondu Dvor_nik 2017-08-04 09:55:34

j'ai trouvé une réponse beaucoup plus simple à cette question par l'utilisateur shaun sur un autre fil: https://stackoverflow.com/a/6445871/2340705

le problème de base est que la propriété changed event est avalée. Certains auraient appelé ce un bug. Pour contourner cette utilisation BeginInvoke du répartiteur pour forcer la propriété changed event à être remis dans la file d'attente end of UI event. Cela ne nécessite aucun changement au xaml, aucune classe de comportement supplémentaire, et un une seule ligne de code changée pour le modèle de vue.

4
répondu CNad 2017-05-23 10:31:29

le problème est qu'une fois que WPF met à jour la valeur avec la propriété setter, il ignore toute autre notification de changement de propriété de l'intérieur de cet appel: il suppose qu'ils se produiront comme une partie normale du setter et sont sans conséquence, même si vous avez réellement mis à jour la propriété retour à la valeur originale.

la façon dont j'ai contourné ce problème était de permettre au champ d'être mis à jour, mais aussi de faire la queue sur une action du répartiteur pour" annuler " le changement. Action il faudrait revenir à l'ancienne valeur et lancer une notification de changement de propriété pour que WPF réalise que ce n'est pas vraiment la nouvelle valeur qu'il pensait qu'elle était.

de toute évidence, l'action" Annuler " doit être mise en place afin qu'elle ne déclenche aucune logique commerciale dans votre programme.

3
répondu RandomEngy 2011-10-17 22:37:21

j'ai eu le même problème, causes par UI thread et la façon dont biding fonctionne. Vérifier le lien suivant: SelectedItem on ComboBox

la structure de l'échantillon utilise le code derrière mais le MVVM est exactement le même.

2
répondu Fred Jand 2017-05-23 12:26:24

je préfère le code de" splintor " à "AngelWPF". Leurs approches sont assez similaires. J'ai mis en œuvre le comportement ci-joint, Annulableselectionbehavior, et il fonctionne comme annoncé. Peut-être que c'était juste que le code dans l'exemple de splintor était plus facile à brancher dans mon application. Le code dans le comportement ci-joint D'AngelWPF avait des références à un type de KeyValuePair qui aurait exigé plus de modification de code.

dans ma demande, j'avais ComboBox où les éléments affichés dans un DataGrid sont basés sur l'élément sélectionné dans le ComboBox. Si l'Utilisateur a fait des changements à la DataGrid, puis a sélectionné un nouvel élément dans le ComboBox, je voudrais demander à l'utilisateur de sauvegarder les changements avec les boutons Oui|Non|annuler comme options. S'ils ont appuyé sur Cancel, je voulais ignorer leur nouvelle sélection dans le ComboBox et garder l'ancienne sélection. Ça a marché comme un champion!

pour ceux qui effraient au moment où ils voient des références à Mélange et du Système.Windows.Interactivité, vous ne devez pas avoir Microsoft Expression Blend installé. Vous pouvez télécharger le SDK Blend pour .NET 4 (ou Silverlight).

Blend SDK for .NET 4

Blend SDK for Silverlight 4

Oh, oui, dans mon XAML, j'utilise ce que ma déclaration d'espace de noms pour se Fondre dans cet exemple:

xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
1
répondu Andy 2012-05-16 13:40:20

voici le flux général que j'utilise (ne nécessite aucun comportement ou modifications XAML):

  1. j'ai juste laissé le changement passer à travers le modèle de vue et de garder la trace de ce qui est passé avant. (Si votre logique commerciale exige que l'élément sélectionné ne soit pas dans un état invalide, je suggère de le déplacer du côté du modèle). Cette approche est également conviviale pour les listes de diffusion qui sont rendues en utilisant des boutons Radio Comme faire la sortie SelectedItem setter dès que possible n'empêchera pas les boutons radio d'être mis en évidence lorsqu'une boîte de message s'affiche.
  2. j'appelle immédiatement l'événement OnPropertyChanged indépendamment de la valeur transmise.
  3. j'ai mis n'importe quelle logique d'annulation dans un handler et j'ai appelé cela en utilisant SynchronizationContext.Post() (BTW: SynchronizationContext.Post fonctionne également pour les applications Windows Store. Donc si vous avez partagé le code de ViewModel, cette approche fonctionnerait quand même).

    public class ViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
    
        public List<string> Items { get; set; }
    
        private string _selectedItem;
        private string _previouslySelectedItem;
        public string SelectedItem
        {
            get
            {
                return _selectedItem;
            }
            set
            {
                _previouslySelectedItem = _selectedItem;
                _selectedItem = value;
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs("SelectedItem"));
                }
                SynchronizationContext.Current.Post(selectionChanged, null);
            }
        }
    
        private void selectionChanged(object state)
        {
            if (SelectedItem != Items[0])
            {
                MessageBox.Show("Cannot select that");
                SelectedItem = Items[0];
            }
        }
    
        public ViewModel()
        {
            Items = new List<string>();
            for (int i = 0; i < 10; ++i)
            {
                Items.Add(string.Format("Item {0}", i));
            }
        }
    }
    
1
répondu No Ordinary Love 2014-10-05 03:25:58

Je l'ai fait d'une manière similaire à ce que splintor a ci-dessus.

Votre point de vue:

<ComboBox  
ItemsSource="{Binding CompetitorBrands}" 
DisplayMemberPath="Value" 
SelectedValuePath="Key" 
SelectedValue="{Binding Path=CompMfgBrandID, 
Mode=TwoWay,
UpdateSourceTrigger=Explicit}" //to indicate that you will call UpdateSource() manually to get the property "CompMfgBrandID" udpated 
SelectionChanged="ComboBox_SelectionChanged"  //To fire the event from the code behind the view
Text="{Binding CompMFGText}"/>

ci-dessous est le code pour le gestionnaire D'événements" ComboBox_SelectionChanged " à partir du fichier de code derrière la vue. Par exemple, si vous affichez est mavue.xaml, le nom de fichier de code de ce gestionnaire d'événements devrait être myview.XAML.cs

private int previousSelection = 0; //Give it a default selection value

private bool promptUser true; //to be replaced with your own property which will indicates whether you want to show the messagebox or not.

private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            ComboBox comboBox = (ComboBox) sender;
            BindingExpression be = comboBox.GetBindingExpression(ComboBox.SelectedValueProperty);

            if (comboBox.SelectedValue != null && comboBox.SelectedIndex != previousSelection)
            {
                if (promptUser) //if you want to show the messagebox..
                {
                    string msg = "Click Yes to leave previous selection, click No to stay with your selection.";
                    if (MessageBox.Show(msg, "Confirm", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes) //User want to go with the newest selection
                    {

                        be.UpdateSource(); //Update the property,so your ViewModel will continue to do something
                        previousSelection = (int)comboBox.SelectedIndex;  
                    }
                    else //User have clicked No to cancel the selection
                    {
                        comboBox.SelectedIndex = previousSelection; //roll back the combobox's selection to previous one
                    }
                }
                else //if don't want to show the messagebox, then you just have to update the property as normal.
                {
                    be.UpdateSource();
                    previousSelection = (int)comboBox.SelectedIndex;
                }
            }
        }
0
répondu Yongquan 2013-10-11 21:41:16

je pense que le problème est que le ComboBox définit l'élément sélectionné à la suite de l'action de l'utilisateur après avoir défini la valeur de propriété liée. Ainsi, L'élément Combobox change peu importe ce que vous faites dans le modèle de vue. J'ai trouvé une approche différente où vous n'avez pas à plier le modèle MVVM. Voici mon exemple (désolé qu'il soit copié de mon projet et ne corresponde pas exactement aux exemples ci-dessus):

public ObservableCollection<StyleModelBase> Styles { get; }

public StyleModelBase SelectedStyle {
  get { return selectedStyle; }
  set {
    if (value is CustomStyleModel) {
      var buffer = SelectedStyle;
      var items = Styles.ToList();
      if (openFileDialog.ShowDialog() == true) {
        value.FileName = openFileDialog.FileName;
      }
      else {
        Styles.Clear();
        items.ForEach(x => Styles.Add(x));
        SelectedStyle = buffer;
        return;
      }
    }
    selectedStyle = value;
    OnPropertyChanged(() => SelectedStyle);
  }
}

la différence est que je nettoie complètement les articles collectionner et ensuite remplir avec les articles stockés auparavant. Cela force le Combobox à se mettre à jour car j'utilise la classe Generic ObservableCollection. Puis j'ai remis l'article sélectionné à l'article sélectionné qui avait été mis précédemment. Cela n'est pas recommandé pour beaucoup d'articles parce que le nettoyage et le remplissage du combobox est un peu coûteux.

0
répondu Patrick Schimmel 2014-12-26 22:09:27

je voudrais compléter réponse de splintor parce que je suis tombé sur un problème avec l'initialisation retardée dans OnSelectedItemChanged :

quand OnSelectedItemChanged est soulevé avant AssociatedObject est assigné, en utilisant le System.Windows.Threading.Dispatcher.CurrentDispatcher.BeginInvoke peut avoir des effets secondaires indésirables, tels que d'essayer d'initialiser la nouvelle valeur avec la valeur par défaut de la sélection combobox.

donc même si votre modèle de vue est à jour, le comportement va déclencher un changement de la valeur actuelle SelectedItem de ViewModel vers la sélection par défaut du ComboBox stocké dans e.NewValue . Si votre code déclenche une Boîte de Dialogue, l'utilisateur sera averti d'un changement bien qu'il n'y est aucune. Je ne peux pas expliquer pourquoi cela arrive, probablement un problème de synchronisation.

Voici mon fix

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Interactivity;

namespace MyApp
{
    internal class CancellableSelectionBehaviour : Behavior<Selector>
    {
        protected override void OnAttached()
        {
            base.OnAttached();

            if (MustPerfomInitialChange)
            {
                OnSelectedItemChanged(this, InitialChangeEvent);
                MustPerfomInitialChange = false;
            }

            AssociatedObject.SelectionChanged += OnSelectionChanged;
        }

        protected override void OnDetaching()
        {
            base.OnDetaching();

            AssociatedObject.SelectionChanged -= OnSelectionChanged;
        }

        public static readonly DependencyProperty SelectedItemProperty =
            DependencyProperty.Register("SelectedItem", typeof(object), typeof(CancellableSelectionBehaviour),
                new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnSelectedItemChanged));

        public object SelectedItem
        {
            get { return GetValue(SelectedItemProperty); }
            set { SetValue(SelectedItemProperty, value); }
        }

        public static readonly DependencyProperty IgnoreNullSelectionProperty =
            DependencyProperty.Register("IgnoreNullSelection", typeof(bool), typeof(CancellableSelectionBehaviour), new PropertyMetadata(true));

        /// <summary>
        /// Determines whether null selection (which usually occurs since the combobox is rebuilt or its list is refreshed) should be ignored.
        /// True by default.
        /// </summary>
        public bool IgnoreNullSelection
        {
            get { return (bool)GetValue(IgnoreNullSelectionProperty); }
            set { SetValue(IgnoreNullSelectionProperty, value); }
        }

        /// <summary>
        /// OnSelectedItemChanged can be raised before AssociatedObject is assigned so we must delay the initial change. 
        /// Using System.Windows.Threading.Dispatcher.CurrentDispatcher.BeginInvoke has unwanted side effects.
        /// So we use this bool to know if OnSelectedItemChanged must be called afterwards, in OnAttached
        /// </summary>
        private bool MustPerfomInitialChange { get; set; }

        /// <summary>
        /// OnSelectedItemChanged can be raised before AssociatedObject is assigned so we must delay the initial change. 
        /// Using System.Windows.Threading.Dispatcher.CurrentDispatcher.BeginInvoke has unwanted side effects.
        /// So we use this DependencyPropertyChangedEventArgs to save the argument needed to call OnSelectedItemChanged.
        /// </summary>
        private DependencyPropertyChangedEventArgs InitialChangeEvent { get; set; }

        /// <summary>
        /// Called when the SelectedItem dependency property is changed.
        /// Updates the associated selector's SelectedItem with the new value.
        /// </summary>
        private static void OnSelectedItemChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var behavior = (CancellableSelectionBehaviour)d;

            // OnSelectedItemChanged can be raised before AssociatedObject is assigned so we must delay the initial change.
            if (behavior.AssociatedObject == null)
            {
                behavior.InitialChangeEvent = e;
                behavior.MustPerfomInitialChange = true;               
            }
            else
            {
                var selector = behavior.AssociatedObject;
                selector.SelectedValue = e.NewValue;               
            }
        }

        /// <summary>
        /// Called when the associated selector's selection is changed.
        /// Tries to assign it to the <see cref="SelectedItem"/> property.
        /// If it fails, updates the selector's with  <see cref="SelectedItem"/> property's current value.
        /// </summary>
        private void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (IgnoreNullSelection && (e.AddedItems == null || e.AddedItems.Count == 0)) return;
            SelectedItem = AssociatedObject.SelectedItem;
            if (SelectedItem != AssociatedObject.SelectedItem)
            {
                AssociatedObject.SelectedItem = SelectedItem;
            }
        }
    }
}
0
répondu GoJiTa972 2017-05-23 12:03:04