Почему WPF Binding обновляет строки, а не объекты? - PullRequest
1 голос
/ 17 июня 2009

В следующем примере кода вы можете переместить ползунок с немецкого на английский и увидеть, что текстовый блок переводится во время выполнения:

  • обновляется только TextBlock, связанный с строкой
  • TextBlock привязан к словарю не не обновляется

Кажется, что View просто получает объект Dictionary один раз , а затем больше не обновляется. Я пытался Mode = TwoWay , но это не имеет никакого эффекта.

Что мне нужно сделать, чтобы элементы, связанные с объектами , обновлялись посредством привязки?

Вид:

<Window x:Class="TestObjectUpdate234.Views.MainView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:c="clr-namespace:TestObjectUpdate234.Commands"
    Title="Main Window" Height="400" Width="800">
    <StackPanel Margin="10">

        <TextBlock Text="{Binding TranslationEdit}" />
        <TextBlock Text="{Binding Translations[add], Mode=TwoWay}" />

        <StackPanel DockPanel.Dock="Bottom"  Orientation="Horizontal" Margin="0 20 0 0">
            <TextBlock Text="English" Margin="0 0 5 0"/>
            <Slider Name="TheLanguageIndexSlider"

                Minimum="0" 
                Maximum="1" 
                IsSnapToTickEnabled="True"
                Width="100" 
                Margin="5" 
                Value="{Binding LanguageIndex}"
                HorizontalAlignment="Left"/>
            <TextBlock Text="German" Margin="5 0 0 0"/>
        </StackPanel>

    </StackPanel>
</Window>

ViewModel:

using System.Collections.Generic;

namespace TestObjectUpdate234.ViewModels
{
    public class MainViewModel : ViewModelBase
    {

        #region ViewModelProperty: TranslationEdit
        private string _translationEdit;
        public string TranslationEdit
        {
            get
            {
                return _translationEdit;
            }

            set
            {
                _translationEdit = value;
                OnPropertyChanged("TranslationEdit");
            }
        }
        #endregion

        #region ViewModelProperty: Translations
        private Dictionary<string, string> _translations = new Dictionary<string, string>();
        public Dictionary<string, string> Translations
        {
            get
            {
                return _translations;
            }

            set
            {
                _translations = value;
                OnPropertyChanged("Translations");
            }
        }
        #endregion

        #region ViewModelProperty: LanguageIndex
        private int _languageIndex;
        public int LanguageIndex
        {
            get
            {
                return _languageIndex;
            }

            set
            {
                _languageIndex = value;
                OnPropertyChanged("LanguageIndex");
                FillTranslations();
            }
        }
        #endregion

        public MainViewModel()
        {
            _languageIndex = 0; //english
            FillTranslations();

        }

        private void FillTranslations()
        {
            if (_languageIndex == 0)
            {
                TranslationEdit = "Edit";

                Translations.Clear();
                Translations.Add("add", "Add");
            }
            else
            {
                TranslationEdit = "Bearbeiten";

                Translations.Clear();
                Translations.Add("add", "Hinzufügen");
            }

        }


    }
}

Ответы [ 2 ]

2 голосов
/ 17 июня 2009

Вам нужен эквивалент ObservableList, но для словаря. В Framework нет такого по умолчанию, но статью, описывающую один из способов ее написания, можно найти здесь .

Причина, по которой ваш код не работает в том виде, в котором он сейчас находится, заключается в том, что вы запускаете событие NotifyPropertyChanged в установщике словаря переводов, но поскольку ваш метод FillTranslations не создает новый словарь, установщик не вызывается и событие не срабатывает. Я полагаю, что вы могли бы обойти класс ObservableDictionary, если бы вы создали новый словарь и присвоили его, который, в свою очередь, вызвал бы событие и повторно связал весь список, но в долгосрочной перспективе более эффективно сохранить тот же экземпляр словаря и уведомить элемент управления о том, что коллекция изменилась с помощью шаблона Observable (реализуя INotifyCollectionChanged в словаре)

1 голос
/ 17 июня 2009

Вам нужно использовать ObservableCollection <>.

Связыватель WPF должен быть уведомлен, когда произошли изменения, вы вызываете OnPropertyChanged, когда установлено свойство словаря, но вам также нужно знать, почему уведомлять связыватель об изменении значений внутри словаря. ObservableCollection <> сделает это за вас. Вызывает события, когда элементы добавляются / удаляются из коллекции.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...