我创建了一个包含带有一些自定义行为的TextBox的usercontrol,我想将Text属性绑定到ViewModel中的属性。
我已将问题隔离到示例解决方案中并设法使用ViewModel属性值更新Text属性,但是当我写入文本框并离开文本框时,我的Person.Name属性未更新。
我的usercontrol xaml:
<UserControl x:Class="WpfCustomUserControlBinding.TextBoxReadOnlyLooksDisabled"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Control.Resources>
<Style x:Key="readOnlyTextbox">
<Style.Triggers>
<Trigger Property="TextBoxBase.IsReadOnly" Value="True">
<Setter Property="TextBoxBase.Background" Value="WhiteSmoke" />
<Setter Property="TextBoxBase.Foreground" Value="#FF6D6D6D" />
<Setter Property="TextBox.BorderBrush" Value="DarkGray" />
<Setter Property="TextBoxBase.BorderThickness" Value="1,1,1,1" />
</Trigger>
<Trigger Property="TextBoxBase.IsReadOnly" Value="False">
<Setter Property="TextBoxBase.Background" Value="White" />
<Setter Property="TextBoxBase.Foreground" Value="Black" />
</Trigger>
</Style.Triggers>
</Style>
</Control.Resources>
<TextBox Style="{StaticResource readOnlyTextbox}" x:Name="txtTextBoxBase" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
代码隐藏代码:
public partial class TextBoxReadOnlyLooksDisabled
{
public TextBoxReadOnlyLooksDisabled()
{
InitializeComponent();
}
public static readonly DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof (string)
, typeof (TextBoxReadOnlyLooksDisabled)
,new PropertyMetadata(OnTextChange));
private static void OnTextChange(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var textBoxReadOnlyLooksDisabled = (TextBoxReadOnlyLooksDisabled) d;
textBoxReadOnlyLooksDisabled.txtTextBoxBase.Text = (string) e.NewValue;
}
public string Text
{
get { return (string) GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
}
}
我尝试让样本运行的窗口:
<Window x:Class="WpfCustomUserControlBinding.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:src="clr-namespace:WpfCustomUserControlBinding" Title="MainWindow" Height="153" Width="525">
<Window.Resources>
<src:Person x:Key="myDataSource"/>
</Window.Resources>
<Grid >
<Label Content="Plain vanilla" Height="26" HorizontalAlignment="Left" Margin="12,12,0,0" Name="label1" VerticalAlignment="Top" Width="143" />
<Label Content="Messed up version" Height="26" HorizontalAlignment="Left" Margin="12,61,0,0" Name="label2" VerticalAlignment="Top" Width="143" />
<TextBox Height="23" HorizontalAlignment="Left" Margin="152,15,0,0" x:Name="txtVanlig" VerticalAlignment="Top" Width="251" Text="{Binding Source={StaticResource myDataSource}, Path=Name, Mode=TwoWay}"/>
<src:TextBoxReadOnlyLooksDisabled Height="23" HorizontalAlignment="Left" Margin="152,61,0,0" x:Name="txtVrien" VerticalAlignment="Top" Width="251" Text="{Binding Source={StaticResource myDataSource}, Path=Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
</Grid>
样本值类:
public class Person
{
private string _name = "King Chaos";
public string Name{get{return _name;}set{_name = value;}}
}
提前致谢。 ;)
编辑:添加INotifyPropertyChanged不起作用,因为更新自定义TextBox时不会访问Name的set方法。
答案 0 :(得分:4)
问题是TextBoxReadOnlyLooksDisabled UserControl中的TextBox没有与Text属性的双向绑定 - 您只在属性值更改时以编程方式(在OnTextChanged处理程序中)更新TextBox,反之则不然。
为什么不完全删除已更改的处理程序,而是添加绑定,如下所示:
<UserControl x:Class="WpfCustomUserControlBinding.TextBoxReadOnlyLooksDisabled"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Control.Resources>
//...
</Control.Resources>
<TextBox Style="{StaticResource readOnlyTextbox}"
x:Name="txtTextBoxBase"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Text="{Binding Path=Text, Mode=TwoWay}"/>
不要忘记也相应地设置DataContext:
public partial class TextBoxReadOnlyLooksDisabled : UserControl
{
public TextBoxReadOnlyLooksDisabled()
{
InitializeComponent();
DataContext = this;
}
public static readonly DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string),
typeof(TextBoxReadOnlyLooksDisabled));
public string Text
{
get { return (string)GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
}
}
答案 1 :(得分:1)
您遇到的问题是因为自定义Text
内TextBox
的{{1}}依赖项属性实际上并未绑定到您的“ViewModel”({1当你在TextBoxReadOnlyLooksDisabled
中写一些内容时,Person
dp被更改,但更改不会传播回ViewModel。
您可以执行的操作是将嵌套txtTextBoxBase
的{{1}} dp连接到自定义控件的Text
dp:
Text
答案 2 :(得分:-2)
public class Person : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private string _name = "King Chaos";
public string Name{
get{
return _name;
}
set{
_name = value;
if (PropertyChanged != null)
PropertyChanged(this, new
PropertyChangedEventArgs("Name"));
}
}
}
只要您的模型必须实现INotifyPropertyChanged并在设置属性时更改属性,以便XAML检测到更改并刷新其值。