2013-09-26 101 views
0

我最近使用WPF开始,我有两个问题,绑定..可观察字典和更新绑定

我使用这个ObservableDictionary
当我将其绑定到文本框,它完美的作品,但我有DataGrid的一个问题:

我的按钮绑定:

Text="{Binding AdiDictionary[AssetName], Mode=TwoWay, UpdateSourceTrigger=PropertyChanged} 

我的DataGrid的绑定:

<DataGrid Grid.Row="1" Margin="5" Name="AdiDataGrid" Background="Transparent" IsReadOnly="True" ItemsSource="{Binding AdiDictionary, Mode=OneWay}" AutoGenerateColumns="False"> 
    <DataGrid.Columns> 
     <DataGridTextColumn Header="Meta-Data Name" Binding="{Binding Path=Key}" /> 
     <DataGridTextColumn Header="Meta-Data Attribute" Binding="{Binding Path=Value}" Width="1*"/> 
    </DataGrid.Columns> 
</DataGrid> 

在我的理解它的工作原理像这样因为ObservableDictionary.Value没有实现INotifyPropertyChanged,但是我尝试了多种解决方案,并且我无法使其工作:(

第二件事:用户应该有加载设置文件的可能性。

void LoadAdiSettingsFileExecute() 
{ 
    var loadDialog = new Microsoft.Win32.OpenFileDialog(); 

    loadDialog.DefaultExt = ".txt"; 
    loadDialog.Filter = "Txt files (*.txt)|*.txt"; 

    if ((bool) loadDialog.ShowDialog()) 
    { 
    var textFile = AdiSettingsFile.ReadingSettingsFileToDictionary(loadDialog.FileName); 
    foreach (KeyValuePair<string, string> x in textFile) 
    { 
     AdiDictionary[x.Key] = x.Value; 
    } 
    RaisePropertyChanged("AdiDictionary"); 
    } 
} 

bool CanLoadAdiSettingsFileExecute() 
{ 
    return true; 
} 

public ICommand LoadAdiSettingsFile {get {return new RelayCommand(LoadAdiSettingsFileExecute, CanLoadAdiSettingsFileExecute);}} 

不幸的是,虽然它的工作原理 - 当我调试,看看他们都在那里AdiDictionary值,但它不更新任何文本框或数据网格:(

任何帮助将非常感激的: )

编辑:哦,有一件事我忘了添加 - 当我尝试加载文件在构造函数它在文本框和数据网格工作,所以它可能与绑定问题。

编辑2: 好吧,所以可能noob错误 - 我不知道每个TabItem创建我的ViewModel的新实例,ViewModel构造函数创建我的ObservableDictionary的新实例。所以我改变它是这样的:

private static ObservableDictionary<string, string> _adiDictionary = new ObservableDictionary<string, string>(StringComparer.OrdinalIgnoreCase); 

它工作!然而,它速度很慢。当我更改一个字典值时,我必须等待~7秒来处理所有内容。当我加载一个改变该字典的20个值的文件时,我必须等待一分钟左右才能处理它。你知道为什么吗?

回答

0

你的ObservableDictionary.Value应该实现INotifyPropertyChanged,然后所有的都会神奇地工作。

这是后面的代码:

public partial class MainWindow : Window 
{ 
    public MyDictionary<string, string> Dic 
    { 
     get; 
     set; 
    } 

    public MainWindow() 
    { 
     InitializeComponent(); 
     this.Dic = new MyDictionary<string, string>(); 
     this.DataContext = this; 
    } 

    private void Button_Click(object sender, RoutedEventArgs e) 
    { 
     this.Dic["0"] = new Random().Next().ToString(); 
    } 
} 

public class MyDictionary<TKey, TValue> : Dictionary<TKey, TValue>, INotifyPropertyChanged 
{ 
    public TValue this[TKey index] 
    { 
     get 
     { 
      return base[index]; 
     } 

     set 
     { 
      base[index] = value; 
      if (this.PropertyChanged != null) 
      { 
       this.PropertyChanged(this, new PropertyChangedEventArgs(Binding.IndexerName)); 
      } 
     } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 
} 

这是我在我的XAML:

<StackPanel> 
    <TextBox Text="{Binding Path=Dic[0], Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" /> 
    <Button Content="click me" Click="Button_Click"/> 
</StackPanel> 

它很容易在一个类来实现INotifyPropertyChanged的。只需触发PropertyChanged事件。

+0

你不需经过解释一些吗?我尝试过这样做:public TValue this [TKey key] { get {return(TValue)_keyedEntryCollection [key] .Value; } set { DoSetEntry(key,value); OnPropertyChanged(Binding。IndexerName); } }但它仍然无法正常工作:/ – Pumar

+0

我不知道你在那里做什么,但我在答案中给了你一个例子。仔细阅读。 –

+0

你能看看我的更新吗? – Pumar

0

我觉得你的绑定源是部份CALSS AdiDictionary本身不是那么 这段代码RaisePropertyChanged(“AdiDictionary”)将不会通知你的绑定更新 TextProperty为您除了