Зависимые контролы TextBox

251
29 ноября 2017, 23:09

Привет всем. Поскажите пожалуйста, у меня страница, к которой привязан соответствующий VM со свойствами Width, Height и Depth. Эти свойства привязаны к 3-ем контролам TextBox. Все эти 3 свойства зависимы между собой: если изменяю одно, изменяются остальные два. Как мне привязать их так к контролам TextBox, чтобы при процессе ввода текста в какой-либо, обновлялся текст в двух других. Суть в том, что у меня двусвязная привязка свойств к контролам, но обновление этих контролов происходит только после валидации, тоесть когда оно потеряет фокус. А мне нужно, чтобы после каждого введенного/удаленного символа из TextBox происходило обновление.

Естественно, хотелось бы услышать в рамках MVVM

Answer 1

Установите в привязке UpdateSourceTrigger в значение PropertyChanged:

<TextBox Text="{Binding Value, UpdateSourceTrigger=PropertyChanged}/>

Возможные значения перечислены здесь: Перечисление UpdateSourceTrigger

Answer 2

Если вы пользуетесь MVVM, то контролы должны лишь отражать состояние VM. Это значит, что не контролы должны быть привязаны друг к другу, а свойства VM.

А это уж делается очевидным, тривиальным образом.

class NameEditorVM : VM
{
    string firstName, surname, composedName;
    bool isUpdating = false;
    public string FirstName
    {
        get => firstName;
        set { if (Set(ref firstName, value) && !isUpdating) CalcComposedName(); }
    }
    public string Surname
    {
        get => surname;
        set { if (Set(ref surname, value) && !isUpdating) CalcComposedName(); }
    }
    public string ComposedName
    {
        get => composedName;
        set { if (Set(ref composedName, value) && !isUpdating) SplitComposedName(); }
    }
    void CalcComposedName()
    {
        isUpdating = true;
        ComposedName = FirstName + " " + Surname;
        isUpdating = false;
    }
    void SplitComposedName()
    {
        isUpdating = true;
        string[] parts = ComposedName.Split();
        FirstName = parts[0];
        Surname = string.Join(" ", parts.Skip(1));
        isUpdating = false;
    }
}

Ну и не забудьте, как верно указал в ответе @Андрей, указать в привязке UpdateSourceTrigger=PropertyChanged.

P. S.: Использован стандартный базовый класс:

class VM : INotifyPropertyChanged
{
    protected bool Set<T>(ref T field, T value,
                         [CallerMemberName] string propertyName = null)
    {
        if (EqualityComparer<T>.Default.Equals(field, value))
            return false;
        field = value;
        RaisePropertyChanged(propertyName);
        return true;
    }
    protected void RaisePropertyChanged([CallerMemberName] string propertyName = null) =>
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    public event PropertyChangedEventHandler PropertyChanged;
}
READ ALSO
Паттерн проектирования Future .Net C#

Паттерн проектирования Future .Net C#

В книге Марка Гранда "Шаблоны проектирования" описан паттерн проектирования FutureКто-нибудь использовал данный паттерн в C# и может объяснить...

130
Не могу применить стиль к элементу панели

Не могу применить стиль к элементу панели

Не получается применить стиль к динамическим элементам

202
c# вывод информации

c# вывод информации

Есть код вывода списка удаленных файловТолько вот при компиляции выходит ошибка

215
JsonSerializationException

JsonSerializationException

Self referencing loop detected for property 'normalized' with type Vector3

259