无论如何...我创建了一个用于选择文件的自定义用户控件。它是一个简单的文本框,后面跟着一个包含在网格中的按钮。我正在处理的控件属性名为FilePath,该控件上的文本框与该属性绑定。当单击按钮时,会打开SaveFileDialog并让用户选择文件。用户选择文件后,UI会正确更新。
我似乎遇到的问题是,当我将一个对象绑定到控件(在这种情况下,我有一个具有DocumentFilePath属性的对象)时,当选择新文件时,该对象不会更新。
以下是我的用户控件中相关的代码:
public static readonly DependencyProperty FilePathProperty = DependencyProperty.Register("FilePath", typeof(string), typeof(FileSave), new UIPropertyMetadata(string.Empty, OnFilePathChanged));
public string FilePath
{
get
{
return this.GetValue(FilePathProperty) as string;
}
set
{
this.SetValue(FilePathProperty, value);
this.OnPropertyChanged("FilePath");
}
}
private void OnPropertyChanged(string propName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propName));
}
}
private static void OnFilePathChanged(object sender, DependencyPropertyChangedEventArgs e)
{
((FileSave)sender).OnPropertyChanged("FilePath");
}
我通过反射在我的对象上将用户控件程序化地添加到我的窗口程序中:
private void AddFileSave(PropertyInfo pi)
{
FileSave fs = new FileSave();
Binding b = new Binding(pi.Name);
fs.SetBinding(FileSave.FilePathProperty, b);
this.AddToGrid(fs); //adds the control into my window's grid in the correct row and column; nothing fancy here
}
值得注意的是,如果我加载一个已存在的对象窗口,我的用户控件将正确显示,但仍无法注册到其绑定的对象中进行任何更改。如果您需要更多信息,请告诉我。
谢谢,Sonny
编辑:我已经找到了解决问题的方法,但这可能不是一个好的解决方案。通过仔细观察调试器,我发现当我在控件内设置FilePath属性时,对象被取消绑定。如果有人能够解释一下,我将非常感激。同时,我已更改打开SaveFileDialog的代码如下:
private void Button_Click(object sender, RoutedEventArgs e)
{
Microsoft.Win32.OpenFileDialog ofd = new Microsoft.Win32.OpenFileDialog();
ofd.Multiselect = false;
ofd.Title = "Select document to import...";
ofd.ValidateNames = true;
ofd.ShowDialog();
if (this.GetBindingExpression(FilePathProperty) == null)
{
this.FilePath = ofd.FileName;
}
else //set value on bound object (THIS IS THE NEW PORTION I JUST ADDED)
{
BindingExpression be = this.GetBindingExpression(FilePathProperty);
string propName = be.ParentBinding.Path.Path;
object entity = be.DataItem;
System.Reflection.PropertyInfo pi = entity.GetType().GetProperty(propName);
pi.SetValue(entity, ofd.FileName, null);
}
if (!string.IsNullOrWhiteSpace(this.FilePath))
{
_fileContents = new MemoryStream();
using (StreamReader sr = new StreamReader(this.FilePath))
{
_fileContents = new MemoryStream(System.Text.ASCIIEncoding.ASCII.GetBytes(sr.ReadToEnd()));
}
}
else
{
_fileContents = null;
}
}