gpt4 book ai didi

c# - 在 wpf 用户控件中公开一个字段供外部使用

转载 作者:行者123 更新时间:2023-11-30 21:41:37 24 4
gpt4 key购买 nike

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

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

<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 中,将控件属性绑定(bind)到这些属性。

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。我对此进行了简化,以便布局按照我认为的预期工作。

请注意绑定(bind)如何使用 RelativeSource={RelativeSource AncestorType=UserControl} 绑定(bind)到我们上面在 UserControl 上定义的依赖属性。默认情况下,Binding 将绑定(bind)到 UserControl.DataContext 的属性,但我们没有使用它。原因是,如果我们在此处设置 UserControl.DataContext,这将破坏此答案末尾的最终 XAML 片段中的 viewmodel 属性绑定(bind)。这些绑定(bind)将在我们的控件 上查找这些属性。有解决方法,但它变得丑陋。我在这里完成的方式是最好的,因为它永远不会打破任何人对 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>

在窗口中使用,绑定(bind)到 View 模型属性:

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

最后,我不确定您对 ElementName=parentElementName 的理解是什么。如果这是对父控件的引用,则不能这样做,如果可以的话也不是一个好主意。您不希望 UserControl 受到父控件必须具有特定名称的要求的约束。对该要求的回答很简单,即 XAML 中的控件只有在具有固定大小时才负责调整自身的大小。如果他们应该调整父级大小,那么父级始终是对此负责的人。因此,如果您想将 TextBoxUsrCtrl 的两个实例调整到两个不同的父项,那很好。每个 parent 都随心所欲地调整自己 child 的大小。

关于c# - 在 wpf 用户控件中公开一个字段供外部使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43127177/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com