为什么WPF绑定更新字符串而不是对象?

时间:2009-06-17 09:32:08

标签: c# wpf xaml binding

在下面的代码示例中,您可以将滑块从德语移动到英语,并看到该文本块在运行时被翻译,但是:

  • 只有绑定到字符串的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>

视图模型:

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 个答案:

答案 0 :(得分:2)

您需要等效的ObservableList,但需要一个Dictionary。框架中没有默认值,但可以找到描述编写一种方法的文章here.

您的代码现在不能正常工作的原因是因为您在Translations Dictionary的setter中触发NotifyPropertyChanged事件,但由于您的FillTranslations方法没有创建新的Dictionary,因此不会调用setter而事件不会发生。我想你可以回避ObservableDictionary类,如果你创建了一个新的字典并分配了它,它又会触发事件并重新绑定整个列表,但从长远来看,保持相同的字典实例并通知控件更有效通过Observable模式更改了集合(在字典上实现了INotifyCollectionChanged)

答案 1 :(得分:1)

您需要使用ObservableCollection&lt;&gt;代替。

当发生更改时,必须通知WPF绑定程序,在设置字典属性时调用OnPropertyChanged,但是还需要通知绑定程序字典中的值已更改的原因。 ObservableCollection&lt;&gt;会为你做这件事。当从集合中添加/删除项目时,它会引发事件。