我最近开始使用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 :(
任何帮助将不胜感激:)
编辑:哦,有一件事我忘了添加 - 当我尝试在构造函数中加载文件时,它在textbox和datagrid中工作,所以它可能与Bindings有关。编辑2: 好吧,可能是noob错误 - 我不知道每个TabItem都在创建我的ViewModel的新实例,而ViewModel构造函数正在创建我的ObservableDictionary的新实例。所以我把它改成了这样的东西:
private static ObservableDictionary<string, string> _adiDictionary = new ObservableDictionary<string, string>(StringComparer.OrdinalIgnoreCase);
它的工作原理!然而它的速度很慢......当我改变一个字典值时,我必须等待~7秒才能处理所有内容。当我加载一个更改该字典大约20个值的文件时,我必须等待大约一分钟才能处理它。你知道为什么吗?
答案 0 :(得分:2)
你的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事件。
答案 1 :(得分:0)
我认为你的绑定源是calss AdiDictionary本身并非如此 此代码RaisePropertyChanged(“AdiDictionary”)不会通知您的绑定更新 TextProperty作为你的