在WPF中创建自定义UI元素

8

我在代码中有几个带有标签的文本框,这些文本框使用以下XAML实现:

<DockPanel HorizontalAlignment="Right">
    <TextBlock Foreground="Black" Padding="0,0,10,0">Serial Number:</TextBlock>
    <TextBox Width="150" IsReadOnly="True" BorderBrush="Gainsboro" Height="20"></TextBox>
</DockPanel>

我可以通过类似以下的方式减少一些复制的代码:
<DockPanel HorizontalAlignment="Right">
    <TextBlock Style="{StaticResource CstmTextBoxLbl}">Serial Number:</TextBlock>
    <TextBox Style="{StaticResource CstmTextBox}"></TextBox>
</DockPanel>

但是它仍然有点冗长。是否可能这样做:
<controls:CstmTextBox Style="{StaticResource CstmTextBox}" LabelText="Serial Number:" Text=""/>

在这种情况下,CstmTextBox将实现所需的任何XAML,以便一次性获得相同的视觉效果,并且我可以在代码中访问TextBlock文本和TextBox文本。例如:

CstmTextBox textbox;
textbox.LabelText = "Serial Number:";
String some_text = textbox.Text;

textbox.Text = "....";

3
创建一个用户控件。 - Clemens
2个回答

5

在你的解决方案中添加一个UserControl,并将要重用的XAML复制到其中。

如果你在UserControl内部设置控件的x:Name属性...

<UserControl ... >
    <DockPanel HorizontalAlignment="Right">
        <TextBlock x:Name="SerialNumberTextBlock" Style="{StaticResource CstmTextBoxLbl}">Serial Number:</TextBlock>
        <TextBox x:Name="SerialNumberTextBox" Style="{StaticResource CstmTextBox}"></TextBox>
    </DockPanel>
</UserControl>

你可以像这样从外部(代码后台)访问它们:

CstmTextBox textbox;
textbox.SerialNumberTextBlock.Text = "Serial Number:";
String some_text = textbox.SerialNumberTextBox.Text;

textbox.SerialNumberTextBox.Text = "....";

如果您创建 DependencyProperties 来公开属性,那就更好了。您可以在 UserControl 的 Code-behind 中定义这些属性:

public string Text
{
    get
    {
        return (string)GetValue(TextProperty);
    }
    set
    {
        SetValue (TextProperty, value);
    }
}

public static readonly DependencyProperty TextProperty = 
    DependencyProperty.Register("Text", typeof(string), typeof (CstmTextBox));

然后将这些属性绑定到您的UserControl内部的控件上:
<UserControl x:Name="Root" ... >
    <DockPanel HorizontalAlignment="Right">
        <TextBlock x:Name="SerialNumberTextBlock" Style="{StaticResource CstmTextBoxLbl}"
                   Text="{Binding LabelText, ElementName=Root}" />
        <TextBox x:Name="SerialNumberTextBox" Style="{StaticResource CstmTextBox}"
                 Text="{Binding Text, ElementName=Root, Mode=TwoWay}" />
    </DockPanel>
</UserControl>

那样一来,您可以直接从外部设置属性,无论是在代码后台、XAML还是绑定中。

4
一个UserControl或CustomControl可以满足您的需求。这是一个CustomControl的代码。
C#:
public class CstmTextBox : Control
{
    public string LabelText
    {
        get
        {
            return (string)GetValue (LabelTextProperty);
        }
        set
        {
            SetValue (LabelTextProperty, value);
        }
    }

    public static readonly DependencyProperty LabelTextProperty =
        DependencyProperty.Register ("LabelText", typeof (string), typeof (CstmTextBox), new PropertyMetadata (string.Empty));

    public string Text
    {
        get
        {
            return (string)GetValue (TextProperty);
        }
        set
        {
            SetValue (TextProperty, value);
        }
    }

    public static readonly DependencyProperty TextProperty =
        DependencyProperty.Register ("Text", typeof (string), typeof (CstmTextBox), new PropertyMetadata (string.Empty));
}

XAML:

    <Style TargetType="{x:Type controls:CstmTextBox}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type controls:CstmTextBox}">
                    <DockPanel HorizontalAlignment="Right">
                        <TextBlock Foreground="Black" Padding="0,0,10,0" Text="{TemplateBinding LabelText}"/>
                        <TextBox Width="150" IsReadOnly="True" BorderBrush="Gainsboro" Height="20" Text="{TemplateBinding Text}"/>
                    </DockPanel>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

将样式添加到您的资源中并使用新控件:
    <controls:CstmTextBox LabelText="abcde" Text="1234"/>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接