我是一位很长时间的读者,但是第一次在这里发布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