如何在wpf UserControl中参数化绑定?

时间:2018-05-25 10:50:54

标签: c# wpf xaml mvvm

我有一个wpf窗口(MyWindow),其DataContext设置为MyViewModel视图模型类:

MyWindow.xaml

<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>

MyWindow.xaml.cs

public class MyWindow : Window
{
    MyWindow()
    {
       InitializeComponent();
       DataContext = new MyViewModel();
    }
}

MyViewModel.cs

// MyViewModel implements IPropertyChanged
public class MyViewModel : INotifyPropertyChanged
{
    public string MyText { get { ... } set { ... } }

    ...
}

我想将MyText的{​​{1}}属性绑定到以下UserControl(MyWindow):

MyUserControl.xaml

MyUserControl

MyUserControl.xaml.cs

<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(); } } Textbox下的内容输入MyUserControl如何实现这一目标?

我尝试将MyViewModel.MyText绑定到MyText中的Text属性,然后将MyUserControl中的Text绑定到TextBox Text 1}}但这不起作用。

2 个答案:

答案 0 :(得分:1)

摆脱TextPropertyChangedHandler

DP只需要BindsTwoWayByDefault标志,没有回叫

public static readonly DependencyProperty TextProperty = DependencyProperty.Register(
    "Text",
    typeof(string),
    typeof(MyUserControl),
    new FrameworkPropertyMetadata(null,
        FrameworkPropertyMetadataOptions.BindsTwoWayByDefault)
);

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>

验证属性应该转到Window中的绑定:

<MyUserControl Text="{Binding MyText, Mode=TwoWay, ValidatesOnDataErrors=True, NotifyOnValidationError=True}" />

答案 1 :(得分:0)

我终于以编程方式从UserControl绑定到视图模型中的属性。

seq(hm('09:00'), hm('10:30'), hm('00:30')) #> Note: method with signature 'Period#ANY' chosen for function '-', #> target signature 'Period#Period'. #> "ANY#Period" would also be valid #> estimate only: convert to intervals for accuracy #> Error in if (sum(values - trunc(values))) {: argument is not interpretable as logical 的用法如下:

MyUserControl

我只是将我希望绑定到的View Model的属性名称传递给用户控件。

然后在用户控件中,我确保按<UserControls:MyUserControl TargetPropertyName="TestId"/> 上的名称以编程方式绑定属性(此处位于MainTextBox中):

BindTextPropertyToTargetPropertyNameOnce

但我仍然认为这是一种解决方法,必须有更好的解决方案。