繁体   English   中英

在WPF用户控件中公开一个字段以供外部使用

[英]expose a field in wpf user control for external use

我是wpf的新手,我想创建一个由文本块和文本框组成的简单用户控件,以便我可以重用它。 但是,我真的不知道如何绑定文本块的内容,以便可以从外部设置它并公开文本框,以便可以从外部调用xaml将其绑定到其他字段。

以下是我的用户控件的代码

<UserControl x:Class="WPFLib.UserControlLibs.TextBoxUsrCtrl"
                         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"
                         xmlns:local="clr-namespace:WPFLib.UserControlLibs"
                         mc:Ignorable="d"
                         d:DesignHeight="20"
                         d:DesignWidth="300">
    <StackPanel Orientation='Horizontal'
                            Width='{Binding ActualWidth, ElementName=parentElementName}'
                            Height='{Binding ActualWidth, ElementName=parentElementName}'>
        <Grid HorizontalAlignment='Stretch'>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width='1*' />
                <ColumnDefinition Width='1*' />
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="*" />
            </Grid.RowDefinitions>
            <TextBlock Text='{Binding Text, ElementName=parentElementName}'
                                 Background='Aqua'
                                 Grid.Column='0'
                                 Grid.Row='0' />
            <TextBox x:Name='UserTxBox'
                             Grid.Column='1'
                             Grid.Row='0'
                             Background='Red'
                             HorizontalAlignment='Stretch'
                             Text='this is a test to see how it works' />
        </Grid>
    </StackPanel>
</UserControl>

如何从TextBlock和TextBox中公开文本,以便可以设置它并从调用xaml中检索它?

例如

        <Window x:Class="TestWPF.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:TestWPF"
                          xmlns:controls='clr-namespace:WPFLib.UserControlLibs'
    `                   mc:Ignorable="d"
                        Title="MainWindow"
                        Height="350"
                        Width="525"
                        WindowState='Maximized'
                        FontSize='18'>
            <StackPanel>                                    
<controls:TextBoxUsrCtrl Width='500' HorizontalAlignment='Left' **Text='NEED TO SET THE TEXT BLOCK HERE'**/>
            </StackPanel>
        </Window>

您应该为它提供两个依赖项属性,对于要公开的两个文本属性,每个属性都应具有一个属性(这真是令人难以置信;我使用Visual Studio的代码段功能来生成所有这些属性)。 然后在UserControl XAML中,将控件属性绑定到那些控件。

public partial class TextBoxUsrCtrl : UserControl
{
    public TextBoxUsrCtrl()
    {
        InitializeComponent();
    }

    #region Text Property
    public String Text
    {
        get { return (String)GetValue(TextProperty); }
        set { SetValue(TextProperty, value); }
    }

    public static readonly DependencyProperty TextProperty =
        DependencyProperty.Register(nameof(Text), typeof(String), typeof(TextBoxUsrCtrl),
            new FrameworkPropertyMetadata(null) {
                //  It's read-write, so make it bind both ways by default
                BindsTwoWayByDefault = true
            });
    #endregion Text Property

    #region DisplayText Property
    public String DisplayText
    {
        get { return (String)GetValue(DisplayTextProperty); }
        set { SetValue(DisplayTextProperty, value); }
    }

    public static readonly DependencyProperty DisplayTextProperty =
        DependencyProperty.Register(nameof(DisplayText), typeof(String), typeof(TextBoxUsrCtrl),
            new PropertyMetadata(null));
    #endregion DisplayText Property
}

XAML。 我对此进行了简化,因此布局可以按照您的预期工作。

请注意,绑定如何使用RelativeSource={RelativeSource AncestorType=UserControl}绑定到我们在UserControl上定义的依赖项属性。 默认情况下, Binding将绑定到UserControl.DataContext属性,但是我们没有使用它。 原因是,如果在此处设置UserControl.DataContext ,则会在此答案的最后破坏最终XAML片段中的viewmodel属性绑定。 这些绑定将在控件上寻找那些属性。 有一些解决方法,但它变得丑陋。 我在这里完成此操作的方式是最好的,因为它永远不会破坏任何人对DataContext继承的假设。

<UserControl 
    x:Class="WPFLib.UserControlLibs.TextBoxUsrCtrl"
    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"
    xmlns:local="clr-namespace:WPFLib.UserControlLibs"
    mc:Ignorable="d"
    d:DesignHeight="20"
    d:DesignWidth="300"
    >
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width='*' />
            <ColumnDefinition Width='*' />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        <TextBlock 
            Text='{Binding DisplayText, RelativeSource={RelativeSource AncestorType=UserControl}}'
            Background='Aqua'
            Grid.Column='0'
            Grid.Row='0' 
            />
        <TextBox 
            x:Name='UserTxBox'
            Grid.Column='1'
            Grid.Row='0'
            Background='Red'
            HorizontalAlignment='Stretch'
            Text='{Binding Text, RelativeSource={RelativeSource AncestorType=UserControl}}'
            />
    </Grid>
</UserControl>

在窗口中的用法,绑定到viewmodel属性:

    <local:TextBoxUsrCtrl
        Text="{Binding TestText}"
        DisplayText="{Binding ShowThisText}"
        />

最后,我不确定您使用ElementName=parentElementName得到什么。 如果这是对父控件的引用,则不能这样做,如果可以的话,也不是一个好主意。 您不希望UserControl受到父控件必须具有特定名称的要求的约束。 该要求的答案很简单,即XAML中的控件仅在大小固定的情况下才负责调整自身大小。 如果他们要适合父母,那么父母永远是负责任的人。 因此,如果您想将TextBoxUsrCtrl两个实例的大小TextBoxUsrCtrl为两个不同的父级,那就很好。 每个父母都可以根据自己的意愿给自己的孩子定尺寸。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM