1

我最近开始使用 WPF,但绑定有两个问题。

我正在使用这个ObservableDictionary
当我将它绑定到 TextBox 时,它可以完美运行,但 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 值时,它们都在那里,但是它不会更新任何 TextBoxes 或 DataGrid:(

任何帮助都感激不尽:)

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

编辑 2:好的,所以可能是菜鸟错误 - 我不知道每个 TabItem 都在创建我的 ViewModel 的新实例,而 ViewModel 构造函数正在创建我的 ObservableDictionary 的新实例。所以我把它改成这样:

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

它有效!但是它的速度很慢。当我更改字典的一个值时,我必须等待约 7 秒才能处理所有内容。当我加载一个更改该字典大约 20 个值的文件时,我必须等待大约一分钟才能处理它。你知道为什么吗?

4

2 回答 2

3

Your ObservableDictionary.Value should implement INotifyPropertyChanged and then all will work magically.

This is code behind:

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;
}

This is what I have in my XAML:

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

Its easy to implement INotifyPropertyChanged in a class. Just fire the PropertyChanged event.

于 2013-09-26T12:06:38.260 回答
0

我认为您的绑定源在 ths 类 AdiDictionary 中而不是它本身,因此此代码 RaisePropertyChanged("AdiDictionary") 不会通知您的绑定以将 TextProperty 更新为您的 except

于 2013-09-26T12:42:01.720 回答