用户控件绑定在值更新时丢失,标准文本框控件不会发生这种情况
Usercontrol binding lost on value updated, that doesn't happen with standard textbox control
我在用户控件中绑定时遇到问题。
这是我的用户控件:
UserControl1.xaml
<UserControl x:Class="WpfApp1.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-ompatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
x:Name="usercontrol"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<TextBox Text="{Binding HmiField, ElementName=usercontrol}"/>
</Grid>
</UserControl>
UserControl1.xaml.cs
namespace WpfApp1
{
public partial class UserControl1 : UserControl
{
public double HmiField
{
get { return (double)GetValue(HmiFieldProperty); }
set { SetValue(HmiFieldProperty, value); }
}
public static readonly DependencyProperty HmiFieldProperty =
DependencyProperty.Register("HmiField", typeof(double), typeof(UserControl1));
public UserControl1()
{
InitializeComponent();
}
}
}
这是主要的 window:
MainWindow.xaml
<Window x:Class="WpfApp1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
DataContext="{Binding Md, RelativeSource={RelativeSource Self}}"
Title="MainWindow" Height="450" Width="800">
<UniformGrid>
<Button Content="{Binding Prop1}" Click="Button_Click"/>
<Label Content="{Binding Prop1}"/>
<TextBox Text="{Binding Prop1}"/>
<local:UserControl1 HmiField="{Binding Prop1}"/>
</UniformGrid>
</Window>
MainWindow.xaml.cs
namespace WpfApp1
{
public class tMd: INotifyPropertyChanged
{
#region Interfaccia INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(string propName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
}
#endregion
private double prop1;
public double Prop1 { get
{
return prop1;
}
set
{
if (prop1 != value)
{
prop1 = value;
NotifyPropertyChanged("Prop1");
}
}
}
}
public partial class MainWindow : Window
{
public tMd Md
{
get { return (tMd)GetValue(MdProperty); }
set { SetValue(MdProperty, value); }
}
public static readonly DependencyProperty MdProperty =
DependencyProperty.Register("Md", typeof(tMd), typeof(MainWindow), new PropertyMetadata(new tMd()));
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Md.Prop1 = 1234.5678;
}
}
}
我发现了一些类似的问题:
How do I change TextBox.Text without losing the binding in WPF?
但我无法完全理解发生了什么:为什么标准文本框按预期工作而我的用户控件却没有?
或者更好:有没有办法让我的用户控件与文本框的行为一起工作?
绑定必须是双向的,或者显式设置
<local:UserControl1 HmiField="{Binding Prop1, Mode=TwoWay}"/>
或默认隐式:
public static readonly DependencyProperty HmiFieldProperty =
DependencyProperty.Register(
nameof(HmiField), typeof(double), typeof(UserControl1),
new FrameworkPropertyMetadata(
0d, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
TextBox 的 Text
属性 已如上所示注册,即带有 BindsTwoWayByDefault
标志。
在用户控件 XAML 的 TextBox
绑定中,您可能还想在用户输入时更新源 属性(而不是仅在失去焦点时):
<TextBox Text="{Binding HmiField,
ElementName=usercontrol,
UpdateSourceTrigger=PropertyChanged}"/>
或没有生成无用的 usercontrol
字段:
<TextBox Text="{Binding HmiField,
RelativeSource={RelativeSource AncestorType=UserControl}
UpdateSourceTrigger=PropertyChanged}"/>
你的 Prop1 会在它发生变化时发出通知,但你没有告诉你绑定触发该通知。
尝试在您的绑定中包含 UpdateSourceTrigger=PropertyChanged
我在用户控件中绑定时遇到问题。
这是我的用户控件:
UserControl1.xaml
<UserControl x:Class="WpfApp1.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-ompatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
x:Name="usercontrol"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<TextBox Text="{Binding HmiField, ElementName=usercontrol}"/>
</Grid>
</UserControl>
UserControl1.xaml.cs
namespace WpfApp1
{
public partial class UserControl1 : UserControl
{
public double HmiField
{
get { return (double)GetValue(HmiFieldProperty); }
set { SetValue(HmiFieldProperty, value); }
}
public static readonly DependencyProperty HmiFieldProperty =
DependencyProperty.Register("HmiField", typeof(double), typeof(UserControl1));
public UserControl1()
{
InitializeComponent();
}
}
}
这是主要的 window:
MainWindow.xaml
<Window x:Class="WpfApp1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
DataContext="{Binding Md, RelativeSource={RelativeSource Self}}"
Title="MainWindow" Height="450" Width="800">
<UniformGrid>
<Button Content="{Binding Prop1}" Click="Button_Click"/>
<Label Content="{Binding Prop1}"/>
<TextBox Text="{Binding Prop1}"/>
<local:UserControl1 HmiField="{Binding Prop1}"/>
</UniformGrid>
</Window>
MainWindow.xaml.cs
namespace WpfApp1
{
public class tMd: INotifyPropertyChanged
{
#region Interfaccia INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(string propName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
}
#endregion
private double prop1;
public double Prop1 { get
{
return prop1;
}
set
{
if (prop1 != value)
{
prop1 = value;
NotifyPropertyChanged("Prop1");
}
}
}
}
public partial class MainWindow : Window
{
public tMd Md
{
get { return (tMd)GetValue(MdProperty); }
set { SetValue(MdProperty, value); }
}
public static readonly DependencyProperty MdProperty =
DependencyProperty.Register("Md", typeof(tMd), typeof(MainWindow), new PropertyMetadata(new tMd()));
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Md.Prop1 = 1234.5678;
}
}
}
我发现了一些类似的问题:
How do I change TextBox.Text without losing the binding in WPF?
但我无法完全理解发生了什么:为什么标准文本框按预期工作而我的用户控件却没有?
或者更好:有没有办法让我的用户控件与文本框的行为一起工作?
绑定必须是双向的,或者显式设置
<local:UserControl1 HmiField="{Binding Prop1, Mode=TwoWay}"/>
或默认隐式:
public static readonly DependencyProperty HmiFieldProperty =
DependencyProperty.Register(
nameof(HmiField), typeof(double), typeof(UserControl1),
new FrameworkPropertyMetadata(
0d, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
TextBox 的 Text
属性 已如上所示注册,即带有 BindsTwoWayByDefault
标志。
在用户控件 XAML 的 TextBox
绑定中,您可能还想在用户输入时更新源 属性(而不是仅在失去焦点时):
<TextBox Text="{Binding HmiField,
ElementName=usercontrol,
UpdateSourceTrigger=PropertyChanged}"/>
或没有生成无用的 usercontrol
字段:
<TextBox Text="{Binding HmiField,
RelativeSource={RelativeSource AncestorType=UserControl}
UpdateSourceTrigger=PropertyChanged}"/>
你的 Prop1 会在它发生变化时发出通知,但你没有告诉你绑定触发该通知。 尝试在您的绑定中包含 UpdateSourceTrigger=PropertyChanged