如果文本值已更改,则更改自定义文本框的背景 属性
Changing custom TextBox's background property if Text value has changed
我有一个自定义 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");
}
}
现在,问题可能出在为我的 OriginalValue
属性.
设置 DependencyProperty
它们看起来像这样:
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
并且只有在 [=19= 时才会触发改变 Background
的代码] 属性 以编程方式更改,而不是通过 GUI 输入。使用 IValueConverter
会更容易实现吗?一个表单上将有大约 30 个这样的控件。
像这样的东西应该可以工作:
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"/>
这是我当前的代码:
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
。也许如果有一种方法可以在XAML
中设置Text
属性,第一次在代码中将其设置为OriginalValue
,然后比较它是否有进一步的变化?背后的代码能否以某种方式意识到第一次调用事实绑定或类似的事情?如果 XAML
可以不写 OriginalValue
属性 就好了。 OriginalValue
在 V3TextBox
本身的 XAML
中看不到,只 One-way
将它绑定到 Text
.
也可以
我有一个自定义 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");
}
}
现在,问题可能出在为我的 OriginalValue
属性.
DependencyProperty
它们看起来像这样:
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
并且只有在 [=19= 时才会触发改变 Background
的代码] 属性 以编程方式更改,而不是通过 GUI 输入。使用 IValueConverter
会更容易实现吗?一个表单上将有大约 30 个这样的控件。
像这样的东西应该可以工作:
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"/>
这是我当前的代码:
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
。也许如果有一种方法可以在XAML
中设置Text
属性,第一次在代码中将其设置为OriginalValue
,然后比较它是否有进一步的变化?背后的代码能否以某种方式意识到第一次调用事实绑定或类似的事情?如果 XAML
可以不写 OriginalValue
属性 就好了。 OriginalValue
在 V3TextBox
本身的 XAML
中看不到,只 One-way
将它绑定到 Text
.