WPF UserControls:使用依赖项属性实现嵌套UserControl的最佳方法

时间:2014-09-21 18:32:20

标签: c# wpf wpf-controls

我是一位很长时间的读者,但是第一次在这里发布SO。在过去,我总是在今天找到问题的答案:)

基本上,我想在其他UserControl中重用UserControl,同时保持所有依赖属性的工作。我现在工作得很好,但我认为我的实施有点乱。

我的基本UserControl是LabelTextBox:左侧是Label,右侧是TextBox。 Label使用DP作为其内容,宽度和水平对齐。

然后我有另一个UserControl,LabelTextBoxToggle,它使用LabelTextBox UserControl并添加一个复选框控件。现在我将LabelTextBox的DP绑定到LabelTextBoxToggle中定义的实现INotifyPropertyChanged的属性。

它有效,但似乎过于复杂。使用DependencyProperties实现嵌套UserControl的最佳方法是什么?这是我目前的实现如下:

LabelTextBox XAML:

<UserControl x:Name="LTBParent" x:Class="SRUserControlsLib.LabelTextBox"
         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:SRUserControlsLib"
         mc:Ignorable="d"
         d:DesignHeight="20" d:DesignWidth="474" Height="20" Margin="0,5">

<UserControl.Resources>
    <local:WidthToAutoConverter x:Key="WidthToAutoConverter"/>
    <local:EnumToStringConverter x:Key="enumToStringConverter" />
</UserControl.Resources>

<Grid x:Name="LayoutRoot" DataContext="{Binding ElementName=LTBParent, Mode=OneWay}">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto"/>
        <ColumnDefinition/>
    </Grid.ColumnDefinitions>

    <Label x:Name="LTBLabel"
           Content="{Binding LabelContent}"
           Width="{Binding LabelWidth, Converter={StaticResource WidthToAutoConverter}}"
           HorizontalContentAlignment="{Binding LabelHAlign, Converter={StaticResource enumToStringConverter}}"
           HorizontalAlignment="{Binding HorizontalContentAlignment}"
           Padding="10,2,5,2" VerticalContentAlignment="Center" MinWidth="80" Margin="0,0,10,0"
    />
    <TextBox x:Name="LTPTextBox" Text="{Binding TextBoxContent}" Padding="5,0" VerticalContentAlignment="Center" Grid.Column="1" KeyDown="LTPTextBox_KeyDown"/>
</Grid>

LabelTextBox代码隐藏:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace SRUserControlsLib
{
    /// <summary>
    /// Interaction logic for LabelTextBox.xaml
    /// </summary>
    public partial class LabelTextBox : UserControl
    {
        // Using DependencyProperty to bind UI elements
        public String LabelContent
        {
            get { return (String)GetValue( LabelContentProperty ); }
            set { SetValue( LabelContentProperty, value ); }
        }
        public static readonly DependencyProperty LabelContentProperty = 
            DependencyProperty.Register( "LabelContent", typeof( string ), typeof( LabelTextBox ), new PropertyMetadata( "Label Text:" ) );


        public string TextBoxContent
        {
            get { return (string)GetValue( TextBoxContentProperty ); }
            set { SetValue( TextBoxContentProperty, value ); }
        }
        public static readonly DependencyProperty TextBoxContentProperty =
            DependencyProperty.Register( "TextBoxContent", typeof( string ), typeof( LabelTextBox ), new PropertyMetadata( "" ) );


        public float LabelWidth
        {
            get { return (float)GetValue( LabelWidthProperty ); }
            set { SetValue( LabelWidthProperty, value ); }
        }
        public static readonly DependencyProperty LabelWidthProperty =
            DependencyProperty.Register( "LabelWidth", typeof( float ), typeof( LabelTextBox ), new PropertyMetadata( 100f ) );


        public enum HAlignments
        {
            Center,
            Left,
            Right,
            Stretch
        }
        public HAlignments LabelHAlign
        {
            get { return (HAlignments)GetValue( LabelHAlignProperty ); }
            set { SetValue( LabelHAlignProperty, value ); }
        }
        public static readonly DependencyProperty LabelHAlignProperty = 
            DependencyProperty.Register( "LabelHAlign", typeof( HAlignments ), typeof( LabelTextBox ), new PropertyMetadata( HAlignments.Left ) );



        public LabelTextBox( )
        {
            InitializeComponent();
        }

        private void LTPTextBox_KeyDown( object sender, KeyEventArgs e )
        {
            if( e.Key == Key.Enter )
            {
                TextBoxContent = LTPTextBox.Text;
            }
        }
}

LabelTextBoxToggle XAML:

<UserControl x:Name="LTBToggle" x:Class="SRUserControlsLib.LabelTextBoxToggle"
         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:SRUserControlsLib" 
         mc:Ignorable="d"
         DataContext="{Binding Mode=OneWay, RelativeSource={RelativeSource Self}}"
         d:DesignHeight="20" d:DesignWidth="474" Margin="0,5">

<Grid x:Name="LayoutRoot">
    <Grid.ColumnDefinitions>
        <ColumnDefinition/>
        <ColumnDefinition Width="Auto" MinWidth="40"/>
    </Grid.ColumnDefinitions>

    <local:LabelTextBox x:Name="LTBControl"
                        LabelContent="{Binding LabelToggleContent}"
                        TextBoxContent="{Binding TextBoxToggleContent}"
                        IsEnabled="{Binding IsChecked, ElementName=UCCheckBox}"
                        Margin="0"
    />
    <CheckBox x:Name="UCCheckBox" VerticalContentAlignment="Center" Grid.Column="1" HorizontalContentAlignment="Center" HorizontalAlignment="Center" Margin="5,0"/>
</Grid>

LabelTextBoxToggle代码隐藏:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.ComponentModel;

namespace SRUserControlsLib
{
    /// <summary>
    /// Interaction logic for LabelTextBoxToggle.xaml
    /// </summary>
    public partial class LabelTextBoxToggle : UserControl, INotifyPropertyChanged
    {
        private string _labelToggleContent;
        public string LabelToggleContent
        {
            get { return _labelToggleContent; }
            set
            {
                if( value != _labelToggleContent )
                {
                    _labelToggleContent = value;
                    NotifyPropertyChanged( "LabelToggleContent" );
                }
            }
        }

        private string _textboxToggleContent;
        public string TextBoxToggleContent
        {
            get { return _textboxToggleContent; }
            set
            {
                if( value != _textboxToggleContent )
                {
                    _textboxToggleContent = value;
                    NotifyPropertyChanged( "TextBoxToggleContent" );
                }
            }
        }

        public LabelTextBoxToggle( )
        {
            InitializeComponent();
            LabelToggleContent      = "Label:";
            TextBoxToggleContent = "Steph";
        }


        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged( String info )
        {
            if( PropertyChanged != null )
            {
                PropertyChanged( this, new PropertyChangedEventArgs( info ) );
            }
        }
    }
}

有关更好实施的任何建议吗? 谢谢!

的Stephane

0 个答案:

没有答案