代码之家  ›  专栏  ›  技术社区  ›  Edward Tanguay

为什么wpf绑定只更新字符串而不更新对象?

  •  1
  • Edward Tanguay  · 技术社区  · 16 年前

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

    • 只有绑定到 一串 得到更新
    • 绑定到 词典 获得更新

    看来 获取dictionary对象一次 然后就不再更新了。我试过 模式= 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 回复  |  直到 16 年前
        1
  •  2
  •   Martin Harris    16 年前

    你需要一个可观察列表的等价物,但需要一本字典。框架中没有默认值,但可以找到一种描述一种写入方法的文章。 here.

    您的代码现在不能正常工作的原因是,您在翻译字典的setter中触发了notifypropertychanged事件,但是由于您的filltranslations方法没有创建新字典,setter不会被调用,事件也不会被触发。我想,如果您创建了一个新字典并将其分配给ObservableDictionary类,从而触发事件并重新绑定整个列表,那么您可以避开ObservableDictionary类,但从长远来看,保持相同的字典实例并通知控件集合具有通过可观察模式更改(在字典上实现inotifycollectionchanged)

        2
  •  1
  •   Simon P Stevens    16 年前

    您需要使用可观察集合来代替。

    发生更改时必须通知wpf绑定器,设置dictionary属性时调用onpropertychanged,但还需要一些通知绑定器字典中的值已更改的原因。一个可观察的收集<gt;将为您做到这一点。它在从集合中添加/删除项时引发事件。