自定义用户控件不绑定数据

时间:2017-06-05 04:54:43

标签: wpf user-controls custom-controls

我创建了一个具有标签和文本框的用户控件。 我添加了两个DependencyProperties(文本和标签)并将它们绑定到textbox.text和label.content。 但是,我无法看到文本框的文本。

在主窗口中,当我没有绑定任何元素时,标签被显示但是如果我绑定元素则没有显示。文本框没有显示任何一种方式。

这是xaml:

<UserControl x:Class="TestNewLabeltextbox.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-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">
<StackPanel Orientation="Horizontal" Background="White" FlowDirection="RightToLeft">
    <Label x:Name="lbl" Content="{Binding Label, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Width="100"  HorizontalAlignment="Left" Background="blue">
        <Label.Style>
            <Style TargetType="Label">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="Label">
                            <StackPanel Orientation="Horizontal">
                                <Border Background="Blue" Width="200" BorderThickness="0,0,0,0">
                                    <StackPanel Orientation="Horizontal">
                                        <Viewbox StretchDirection="DownOnly" Stretch="Uniform">
                                            <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" RecognizesAccessKey="True" TextBlock.FontSize="14" TextBlock.Foreground="#FFFFFF" Margin="5">
                                                <ContentPresenter.Effect>
                                                    <DropShadowEffect BlurRadius="0.0"
                                              Color="#032A6B"
                                              Direction="90"
                                              Opacity="1"
                                              ShadowDepth="1" />
                                                </ContentPresenter.Effect>
                                            </ContentPresenter>
                                        </Viewbox>
                                    </StackPanel>
                                </Border>
                            </StackPanel>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </Label.Style>
    </Label>
    <TextBox x:Name="txt" Text="{Binding Text, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Width="120" HorizontalAlignment="Right">
        <TextBox.Style>
            <Style TargetType="TextBox">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="TextBox">
                            <Border CornerRadius="0,0,0,50" BorderBrush="Black" Background="White" BorderThickness="0">
                                <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" RecognizesAccessKey="True" TextBlock.FontSize="14" TextBlock.Foreground="#FFFFFF" Margin="5">
                                    <ContentPresenter.Effect>
                                        <DropShadowEffect BlurRadius="0.0"
                                              Color="#032A6B"
                                              Direction="90"
                                              Opacity="1"
                                              ShadowDepth="1" />
                                    </ContentPresenter.Effect>
                                </ContentPresenter>
                            </Border>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </TextBox.Style>
    </TextBox>
</StackPanel>

Here'sUserControl1.cs:

public partial class UserControl1 : UserControl
{
    public UserControl1()
    {
        InitializeComponent();
        this.DataContext = this;
    }

    public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();
    }

    public static readonly DependencyProperty LabelProperty = DependencyProperty.Register("Label", typeof(string), typeof(UserControl1), new PropertyMetadata(null));
    public string Label
    {
        get { return (string)this.GetValue(LabelProperty); }
        set { this.SetValue(LabelProperty, value); }
    }

    public static readonly DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(UserControl1), new PropertyMetadata(null));
    public string Text
    {
        get { return (string)this.GetValue(TextProperty); }
        set { this.SetValue(TextProperty, value); }
    }
}

这是窗口xaml + cs:

<Window x:Class="TestNewLabeltextbox.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:controls="clr-namespace:TestNewLabeltextbox"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <StackPanel Orientation="Vertical" Height="150">
        <controls:UserControl1 Text="hello" Height="50" Label="{Binding Hello, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
        <controls:UserControl1 Text="hello" Height="50" Label="world" />
        <Label BorderBrush="Black" BorderThickness="2" Width="100" Height="50" Content="{Binding Hello, Mode=TwoWay}"/>
    </StackPanel>
</Grid>

public partial class MainWindow : Window
{
    ViewModel vm = new ViewModel();
    public MainWindow()
    {
        InitializeComponent();
        vm.Hello = "555";
        this.DataContext = vm;            
    }
}

viewmodel.cs

public class ViewModel : INotifyPropertyChanged
{
    private string h = "Hello";
    public string Hello
    {
        get
        {
            return h;
        }
        set
        {
            h = value;
            NotifyPropertyChanged("Hello");
        }
    }

    #region "PropertyChanged Event"
    public event PropertyChangedEventHandler PropertyChanged;

    private void NotifyPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
    #endregion   
}

1 个答案:

答案 0 :(得分:0)

绑定的默认SourceDataContext。但是您的LabelText依赖项属性在控件中定义,而不是在视图模型中定义。更改Label

的绑定
{Binding Path=Label, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}}

TextBox

的绑定
{Binding Path=Text, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}

请阅读Mode的{​​{1}}和UpdateSourceTrigger属性。看来你不知道它们是如何工作的。 BindingMode=TwoWay, UpdateSourceTrigger=PropertyChanged属性没有任何意义。