[英]How to parametrize binding in wpf UserControl?
I have a wpf Window ( MyWindow
) with its DataContext
set to the MyViewModel
view model class: 我有一个wpf窗口(
MyWindow
),其DataContext
设置为MyViewModel
视图模型类:
<Window x:Class="MyProject.MyWindow"
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-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d">
<MyUserControl Text="{Binding MyText, Mode=TwoWay}" />
</Window>
public class MyWindow : Window
{
MyWindow()
{
InitializeComponent();
DataContext = new MyViewModel();
}
}
// MyViewModel implements IPropertyChanged
public class MyViewModel : INotifyPropertyChanged
{
public string MyText { get { ... } set { ... } }
...
}
I would like to pass the binding of the MyText
property from MyWindow
to the following UserControl ( MyUserControl
): 我想将
MyText
属性的绑定从MyWindow
传递给以下UserControl( MyUserControl
):
<UserControl x:Class="MyProject.MyUserControl"
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-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d">
<StackPanel>
<TextBox
Name="MainTextBox"
Text="{Binding Text, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, NotifyOnValidationError=True}"
/>
</StackPanel>
</UserControl>
public partial class MyUserControl : UserControl
{
public static readonly DependencyProperty TextProperty = DependencyProperty.Register(
"Text",
typeof(string),
typeof(MyUserControl),
new UIPropertyMetadata(TextPropertyChangedHandler)
);
public static void TextPropertyChangedHandler(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
var MyUserControl = sender as MyUserControl;
MyUserControl.Text = (string)e.NewValue;
}
public string Text
{
get
{
return (string)GetValue(TextProperty);
}
set
{
SetValue(TextProperty, value);
}
}
public MyUserControl()
{
InitializeComponent();
}
}
I would like to get the content typed in the Textbox
under MyUserControl
into MyViewModel.MyText
. 我想将在
MyUserControl
下的Textbox
键入的内容放入MyViewModel.MyText
。 How can this be achieved? 如何做到这一点?
I tried to bind MyText
to the Text
property in MyUserControl
and then subsequently binding Text
in TextBox
to Text
from MyUserControl
but this does not work. 我试图绑定
MyText
到Text
的属性MyUserControl
并随后绑定Text
在TextBox
以Text
从MyUserControl
但这不起作用。
get rid of TextPropertyChangedHandler
. 摆脱
TextPropertyChangedHandler
。
DP needs only BindsTwoWayByDefault
flag, without callback DP仅需要
BindsTwoWayByDefault
标志,而无需回调
public static readonly DependencyProperty TextProperty = DependencyProperty.Register(
"Text",
typeof(string),
typeof(MyUserControl),
new FrameworkPropertyMetadata(null,
FrameworkPropertyMetadataOptions.BindsTwoWayByDefault)
);
TextBox.Text
should bind to MyUserControl.Text
TextBox.Text
应该绑定到MyUserControl.Text
<UserControl x:Class="MyProject.MyUserControl" x:Name="self"
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-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d">
<StackPanel>
<TextBox Text="{Binding Text, Mode=TwoWay, ElementName=self}" />
</StackPanel>
</UserControl>
validation properties should go to binding in Window: 验证属性应转到Window中的绑定:
<MyUserControl Text="{Binding MyText, Mode=TwoWay, ValidatesOnDataErrors=True, NotifyOnValidationError=True}" />
I finally managed to bind to the property in the view model from the UserControl programatically. 我终于设法以编程方式从UserControl绑定到视图模型中的属性。
The MyUserControl
is used as follows: MyUserControl
的用法如下:
<UserControls:MyUserControl TargetPropertyName="TestId"/>
I just pass the name of the property of the View Model that I wish to bind to inside the user control. 我只是将希望绑定到的View模型的属性名称传递给用户控件。
Then inside the user control I make sure to programatically bind the property by name on the MainTextBox
(here in the BindTextPropertyToTargetPropertyNameOnce
): 然后,在用户控件中,我确保以编程方式通过
MainTextBox
上的名称绑定属性(在此处为BindTextPropertyToTargetPropertyNameOnce
):
public partial class MyUserControl : UserControl
{
public static readonly DependencyProperty TargetPropertyNameProperty = DependencyProperty.Register(
"TargetPropertyName",
typeof(string),
typeof(MyUserControl),
new UIPropertyMetadata(TargetPropertyNamePropertyChangedHandler)
);
public static void TargetPropertyNamePropertyChangedHandler(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
var MyUserControl = sender as MyUserControl;
MyUserControl.TargetPropertyName = (string)e.NewValue;
}
public string TargetPropertyName
{
get
{
return (string)GetValue(TargetPropertyNameProperty);
}
set
{
SetValue(TargetPropertyNameProperty, value);
BindTextPropertyToTargetPropertyNameOnce()
}
}
public MyUserControl()
{
InitializeComponent();
}
private bool _firstRun = true;
private void BindTextPropertyToTargetPropertyNameOnce()
{
if (_firstRun)
{
_firstRun = false;
var binding = new Binding(TargetPropertyName)
{
Mode = BindingMode.TwoWay,
UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged,
ValidatesOnDataErrors = true,
NotifyOnValidationError = true
};
MainTextBox.SetBinding(TextBox.TextProperty, binding);
}
}
}
But still I consider this to be a workaround, there must be a better solution. 但是我仍然认为这是一种解决方法,必须有更好的解决方案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.