我有一个自定义TextBox
控件,它继承System.Windows.Controls.TextBox
并实现INotifyPropertyChanged
接口。
public partial class V3TextBox : TextBox, INotifyPropertyChanged
它具有自定义OriginalValue
属性,并且覆盖了基础Text
属性。
我想象它的工作方式是将Text
和OriginalValue
绑定到两个不同的字符串属性,并将其Background
设置为黄色,如果这两个字符串是如果它们再次变得相同,那就不一样了又回到白色。
这些是我的Text
和PropertyChanged
属性:
private Binding PropertyChangedBinding = new Binding()
{
Path = new PropertyPath("ChangedPropertyBackground")
};
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string name)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
private string text { get; set; } = "";
public new string Text
{
get
{
return text;
}
set
{
text = value;
if (value == originalValue)
BindingOperations.ClearBinding(this, BackgroundProperty);
else
SetBinding(BackgroundProperty, PropertyChangedBinding);
OnPropertyChanged("Background");
}
}
现在,问题可能在于为DependencyProperty
属性设置OriginalValue
。
他们看起来像这样:
private string originalValue;
public string OriginalValue
{
get
{
return (string)GetValue(TestProperty);
}
set
{
originalValue = value;
SetValue(TestProperty, value);
}
}
public static readonly DependencyProperty TestProperty =
DependencyProperty.Register("OriginalValue", typeof(string),
typeof(V3TextBox), new FrameworkPropertyMetadata(default(string)));
private void OnTextPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
SetValue(TestProperty, e.NewValue);
}
XAML
中的控件使用情况如下所示:
<Ctrls:V3TextBox x:Name="txtBxDiscountNote"
Text="{Binding EditedNote, Mode=TwoWay, NotifyOnTargetUpdated=True}"
OriginalValue="{Binding OriginalNote, Mode=TwoWay}"/>
DataContext
已在XAML
中设置。
问题是OriginalValue
属性永远不会更改,它总是null
并且只有在以编程方式更改Background
属性时才会触发更改Text
的代码,不通过GUI输入。使用IValueConverter
更容易实现吗?单个表格上将有大约30个这些控件。
答案 0 :(得分:0)
这样的事情应该有效:
public class V3TextBox : TextBox
{
public static readonly DependencyProperty OriginalValueProperty =
DependencyProperty.Register("OriginalValue", typeof(string), typeof(V3TextBox));
public static readonly DependencyProperty ChangedBackgroundProperty =
DependencyProperty.Register("ChangedBackground", typeof(Brush), typeof(V3TextBox));
public string OriginalValue
{
get { return (string)GetValue(OriginalValueProperty); }
set { SetValue(OriginalValueProperty, value); }
}
public Brush ChangedBackground
{
get { return (Brush)GetValue(ChangedBackgroundProperty); }
set { SetValue(ChangedBackgroundProperty, value); }
}
protected override void OnTextChanged(TextChangedEventArgs e)
{
base.OnTextChanged(e);
if (Text == OriginalValue)
{
ClearValue(BackgroundProperty);
}
else
{
Background = ChangedBackground;
}
}
}
像这样使用:
<local:V3TextBox OriginalValue="Hello" ChangedBackground="Yellow"/>
答案 1 :(得分:0)
这是我目前的代码:
public partial class V3TextBox : TextBox
{
public static readonly DependencyProperty OriginalValueProperty =
DependencyProperty.Register("OriginalValue", typeof(string), typeof(V3TextBox));
public string OriginalValue
{
get
{
return (string)GetValue(OriginalValueProperty);
}
set
{
SetValue(OriginalValueProperty, value);
}
}
protected override void OnTextChanged(TextChangedEventArgs e)
{
base.OnTextChanged(e);
if (Text == OriginalValue)
SetResourceReference(BackgroundProperty, "V3CtrlDefaultBackground");
else
SetResourceReference(BackgroundProperty, "V3CtrlChangedBackground");
}
public V3TextBox()
{
InitializeComponent();
}
}
我正在使用它:
<Ctrls:V3TextBox x:Name="txtBxLocID"
OriginalValue="{Binding LocationID, Mode=OneTime}"
Text="{Binding LocationID, Mode=TwoWay}"/>
这意味着,我将Text
和OriginalValue
绑定到同一个属性,但后者设置了Mode=OneTime
。
所以OriginalValue
只被设置一次,并且只要它存活就保持其值,并且我能够将它与当前的Text
值进行比较。
@Clemens我正在使用你的一些代码,所以它会被标记为正确答案,请告诉我你是否对我的代码有任何建议?我需要在XAML
中使用您的代码再设置一个属性,这样我就不会将DependencyProperty
用于Background
Brush
。也许如果有办法在Text
中设置XAML
属性,请在代码中首次将其设置为OriginalValue
,然后将其进行比较以获得进一步的更改?后面的代码可以以某种方式知道第一次调用事实绑定或类似的事情吗?如果XAML
可以在没有OriginalValue
属性的情况下编写,那将会很好。在OriginalValue
本身的XAML
中看不到V3TextBox
,只需One-way
将其绑定到Text
也可以。