Silverlight MVVM - Привязка Twoway не уволена в ListBox Нажмите

StackOverflow https://stackoverflow.com/questions/3602252

  •  25-09-2019
  •  | 
  •  

Вопрос

В приложении Silverlight MVVMLight 4.0 у меня есть список списка, текстовое поле и флажок. Элементы элементов ListBox связаны с списком объектов в ViewModel. Выполненный элемент ListBox является двусторонним привязкой к объекту (выявленности) в ViewModel.

Оба текста TextBox и свойства Isselected CheckBox являются двусторонним значением, связанным с объектом выставленного актексирования (имя и выбранные свойства) в ViewModel. Нет кодовых

Это работает нормально: изменение имени в текстовом поле или проверку / снятие флажков, а затем в табуке изменят основное свойство объекта.

Но когда я изменяю имя (или проверенное состояние), а затем немедленно щелкните другой элемент в списке, изменение не зарегистрировано.

У кого-нибудь есть обходной путь для этого?

с уважением,

Карел

Это XAML:

<ListBox Height="251" HorizontalAlignment="Left" Margin="11,39,0,0" Name="activitiesListBox" ItemsSource="{Binding Activities.Items}" VerticalAlignment="Top" Width="139"
             SelectedItem="{Binding Activities.SelectedActivity, Mode=TwoWay}">

Это класс деятельности, удерживающий элементы, связанные с списком:

public class CLJActivitiesViewModel : ViewModelBase
{
    /// <summary>
    /// Initializes a new instance of the ActivitiesViewModel class.
    /// </summary>
    public CLJActivitiesViewModel()
    {
        ////if (IsInDesignMode)
        ////{
        ////    // Code runs in Blend --> create design time data.
        ////}
        ////else
        ////{
        ////    // Code runs "for real": Connect to service, etc...
        ////}
    }


    #region items
    /// <summary>
    /// The <see cref="Items" /> property's name.
    /// </summary>
    public const string ItemsPropertyName = "Items";

    private ObservableCollection<CLJActivityViewModel> m_Items = null;

    /// <summary>
    /// Gets the Items property.
    /// TODO Update documentation:
    /// Changes to that property's value raise the PropertyChanged event. 
    /// This property's value is broadcasted by the Messenger's default instance when it changes.
    /// </summary>
    public ObservableCollection<CLJActivityViewModel> Items
    {
        get
        {
            return m_Items;
        }

        set
        {
            if (m_Items == value)
            {
                return;
            }

            var oldValue = m_Items;
            m_Items = value;

            RaisePropertyChanged(ItemsPropertyName, oldValue, value, true);
        }
    }
    #endregion

    #region SelectedActivity
    /// <summary>
    /// The <see cref="SelectedActivity" /> property's name.
    /// </summary>
    public const string SelectedActivityPropertyName = "SelectedActivity";

    private CLJActivityViewModel m_SelectedActivity = null;

    /// <summary>
    /// Gets the SelectedActivity property.
    /// TODO Update documentation:
    /// Changes to that property's value raise the PropertyChanged event. 
    /// This property's value is broadcasted by the Messenger's default instance when it changes.
    /// </summary>
    public CLJActivityViewModel SelectedActivity
    {
        get
        {
            return m_SelectedActivity;
        }

        set
        {
            if (m_SelectedActivity == value)
            {
                return;
            }

            var oldValue = m_SelectedActivity;
            m_SelectedActivity = value;

            RaisePropertyChanged(SelectedActivityPropertyName, oldValue, value, true);
        }
    }
    #endregion



    public override void Cleanup()
    {
        // Clean own resources if needed

        base.Cleanup();
    }
}        
Это было полезно?

Решение

Я столкнулся с тем же вопросом. Я должен был вызвать обновление, так как пользователь вводил текст, чтобы я мог сделать некоторую проверку.

Простой способ добиться этого состоит в том, чтобы создать пользовательское поведение, которое вы можете добавить в любой TextBox.

Шахта выглядит следующим образом:

public static class TextChangedBindingBehavior
{
    public static readonly DependencyProperty InstanceProperty =
        DependencyProperty.RegisterAttached("Instance", typeof(object), typeof(TextChangedBindingBehavior), new PropertyMetadata(OnSetInstanceCallback));


    public static object GetInstance(DependencyObject obj)
    {
        return (object)obj.GetValue(InstanceProperty);
    }

    public static void SetInstance(DependencyObject obj, object value)
    {
        obj.SetValue(InstanceProperty, value);
    }

    private static void OnSetInstanceCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var textBox = d as TextBox;
        if (textBox != null)
        {
            textBox.TextChanged -= OnTextChanged;
            textBox.TextChanged += OnTextChanged;
        }
    }

    private static void OnTextChanged(object sender, TextChangedEventArgs e)
    {
        var textBox = (TextBox)sender;

        if(!DesignerProperties.GetIsInDesignMode(textBox))
        {
            textBox.GetBindingExpression(TextBox.TextProperty).UpdateSource();
        }
    }
}

и вы установили его на TextBox как это (Behaviors это пространство имен, где я положил класс выше):

 <TextBox Behaviors:TextChangedBindingBehavior.Instance="" Text="{Binding Name, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}" />

Другие советы

Я бежал в эту проблему с TextBox, но не видел, что он влияет на флажок. Проблема TextBox происходит, потому что связанный текст обновляется, то фокус потерян. Вот почему, если вы сначала вкладка, а затем измените свой выбор, он работает, как вы ожидаете. Если вы измените выбор, напрямую связанный текст не обновляется с тех пор, как утерянное сообщение Focus поступает слишком поздно.

Один из способов решения этой проблемы состоит в том, чтобы заставить обновление связывания каждый раз, когда пользовательские типы пользователей текст в текстовом поле. Вы можете сделать пользовательское поведение, чтобы сохранить его MVVM.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top