【发布时间】:2019-09-20 19:32:07
【问题描述】:
我的问题不是关于序列化我让序列化部分工作得很好,但是对于上下文我试图序列化用户以 WPF 形式设置的一些属性,因此需要双向绑定(我只能朝一个方向工作:目标到源的更新)。
假设我已经定义了一个应用程序属性,它是我想要序列化的属性的容器:
public SerializableApplicationProperties ThisAppsSerializableProperties { get; set; }
SerializableApplicationProperties 类如下所示:
[Serializable]
public class SerializableApplicationProperties
{
public SerializableApplicationProperties()
{
UserSelectedPreFillFilePath = new ObservableString();
}
public SerializableApplicationProperties(string defaultFilePath)
{
UserSelectedPreFillFilePath = new ObservableString(defaultFilePath);
}
public ObservableString UserSelectedPreFillFilePath { get; set; }
}
到目前为止,我已经定义了一个属性,我需要在代码中建立一个双向绑定(是的,在代码中)。请不要建议我如何在 XAML 标记中执行此操作,除非您还完全在代码中解释了如何执行此操作。
属性是“UserSelectedPreFillFilePath”,你可以看到它的类型是“ObservableString”。
ObservableString 类如下所示:
[Serializable]
public class ObservableString : INotifyPropertyChanged
{
private string _stringValue;
public string StringValue
{
get { return _stringValue; }
set
{
_stringValue = value;
OnPropertyChanged("StringValue");
}
}
public ObservableString() { }
public ObservableString(string value)
{
this._stringValue = value;
}
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
一个非常简单的类,它包含一个“StringValue”属性并实现 INotifyChange。
然后,我尝试在此“UserSelectedPreFillFileLocation”和主窗口上的文本框之间建立双向绑定。
我想要一个双向绑定,以便在关闭应用程序之前,我可以序列化 UserSelectedPreFillFileLocation 属性(该属性应该根据用户在窗口文本框中输入的内容自动更新)。
然后,当应用程序从文件加载(反序列化)时,该文本框会通过绑定自动填充 UserSelectedPreFillFileLocation 值。
倒数第二件事,我的转换器类定义:
[ValueConversion(typeof(ObservableString), typeof(string))]
class ObservableStringToStringConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
ObservableString myVar = (ObservableString)value;
return myVar.StringValue;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
string myVar = (string)value;
return new ObservableString(myVar);
}
}
最后是绑定的定义。绑定适用于目标到源,但不是相反。 IE。当用户更新文本框时,UserSelectedPreFillFileLocation 会更新,但不会反过来。
Binding UserSelectedPreFillFilePathBinding = new Binding();
UserSelectedPreFillFilePathBinding.Path = new PropertyPath(nameof(ThisAppsSerializableProperties.UserSelectedPreFillFilePath));
UserSelectedPreFillFilePathBinding.Source = ThisAppsSerializableProperties;
UserSelectedPreFillFilePathBinding.Converter = new ObservableStringToStringConverter();
UserSelectedPreFillFilePathBinding.Mode = BindingMode.TwoWay;
UserSelectedPreFillFilePathBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
ThisAppInstanceMainWindow.TxtbxPrefillFileLocation.SetBinding(TextBox.TextProperty, UserSelectedPreFillFilePathBinding);
【问题讨论】:
-
UserSelectedPreFillFilePath需要在其设置器中提高PropertyChanged。当您替换该属性的值时,您不会通知 UI。或者,您可以将UserSelectedPreFillFilePath设为只读 ObservableString 属性,并且只设置或绑定到它的Value属性。附言在 XAML 中进行绑定。 -
UserSelectedPreFillFilePath 确实在 setter 中更改了属性,不是吗?因为它是 ObservableString 类型(它实现了 INotifyPropertyChanged)。
-
这里是
UserSelectedPreFillFilePath的setter的完整文本:set;。而已。这就是你给我们的一切。它没有引发任何事件,SerializableApplicationProperties没有定义任何事件或实现 INotifyPropertyChanged。您是说实际代码与您的问题不同吗? -
这样想:
ObservableString a = null;ObservableString.Value的 setter 是如何被调用的? -
ObservableString 类没有定义 Value 属性(除非有一些隐含的 Value 属性是我不知道的每个类的一部分)。
标签: c# wpf data-binding