2015-02-28 2 views
0

Я хочу создать несколько пользовательских элементов управления. Вот скриншот того, что я пытаюсь достичь.Подкласс a silverlight templated control

Editor Screenshot

Каждый элемент управления состоит из двух частей, этикетка (TextBlock) и редактор (UIElement). Часть ярлыка является общей для всех элементов управления. Я не хочу указывать метку в каждом настраиваемом элементе управления, который я создаю. Поэтому я подумал о создании базового класса. Вот базовый класс Editor.

[TemplatePart(Name = PartLabelName, Type = typeof (TextBlock))] 
[TemplatePart(Name = PartEditorName, Type = typeof (ContentPresenter))] 
public abstract class Editor : Control 
{ 
    protected const string PartLabelName = "PartLabel"; 
    protected const string PartEditorName = "PartEditor"; 

    public static readonly DependencyProperty LabelStyleProperty = DependencyProperty.Register(
     "LabelStyle", typeof (Style), typeof (Editor), new PropertyMetadata(default(Style))); 

    public static readonly DependencyProperty LabelHeightProperty = DependencyProperty.Register(
     "LabelHeight", typeof (double), typeof (Editor), new PropertyMetadata(default(double))); 

    public static readonly DependencyProperty LabelWidthProperty = DependencyProperty.Register(
     "LabelWidth", typeof (double), typeof (Editor), new PropertyMetadata(default(double))); 

    public static readonly DependencyProperty LabelProperty = DependencyProperty.Register(
     "Label", typeof (string), typeof (Editor), new PropertyMetadata(default(string))); 

    public static readonly DependencyProperty EditorControlProperty = DependencyProperty.Register(
     "EditorControl", typeof (FrameworkElement), typeof (Editor), new PropertyMetadata(default(FrameworkElement))); 

    public static readonly DependencyProperty EditorWidthProperty = DependencyProperty.Register(
     "EditorWidth", typeof (double), typeof (Editor), new PropertyMetadata(default(double))); 

    public static readonly DependencyProperty EditorHeightProperty = DependencyProperty.Register(
     "EditorHeight", typeof (double), typeof (Editor), new PropertyMetadata(default(double))); 

    public static readonly DependencyProperty EditorStyleProperty = DependencyProperty.Register(
     "EditorStyle", typeof (Style), typeof (Editor), new PropertyMetadata(default(Style))); 

    public static readonly DependencyProperty LabelColorProperty = DependencyProperty.Register(
     "LabelColor", typeof (Brush), typeof (Editor), new PropertyMetadata(default(Brush))); 

    private ContentPresenter _partEditorControl; 
    private TextBlock _partLabel; 

    protected Editor() 
    { 
     DefaultStyleKey = typeof (Editor); 
    } 

    public Brush LabelColor 
    { 
     get { return (Brush) GetValue(LabelColorProperty); } 
     set { SetValue(LabelColorProperty, value); } 
    } 

    public Style EditorStyle 
    { 
     get { return (Style) GetValue(EditorStyleProperty); } 
     set { SetValue(EditorStyleProperty, value); } 
    } 

    public double EditorHeight 
    { 
     get { return (double) GetValue(EditorHeightProperty); } 
     set { SetValue(EditorHeightProperty, value); } 
    } 

    public double EditorWidth 
    { 
     get { return (double) GetValue(EditorWidthProperty); } 
     set { SetValue(EditorWidthProperty, value); } 
    } 

    public Style LabelStyle 
    { 
     get { return (Style) GetValue(LabelStyleProperty); } 
     set { SetValue(LabelStyleProperty, value); } 
    } 

    public double LabelHeight 
    { 
     get { return (double) GetValue(LabelHeightProperty); } 
     set { SetValue(LabelHeightProperty, value); } 
    } 

    public double LabelWidth 
    { 
     get { return (double) GetValue(LabelWidthProperty); } 
     set { SetValue(LabelWidthProperty, value); } 
    } 

    public FrameworkElement EditorControl 
    { 
     get { return (FrameworkElement) GetValue(EditorControlProperty); } 
     set { SetValue(EditorControlProperty, value); } 
    } 

    public string Label 
    { 
     get { return (string) GetValue(LabelProperty); } 
     set { SetValue(LabelProperty, value); } 
    } 

    public override void OnApplyTemplate() 
    { 
     base.OnApplyTemplate(); 
     _partLabel = GetTemplateChild(PartLabelName) as TextBlock; 
     _partEditorControl = GetTemplateChild(PartEditorName) as ContentPresenter; 

     if (_partLabel == null || _partEditorControl == null) 
     { 
      throw new NullReferenceException("Template parts are not available"); 
     } 
    } 

И вот стиль для редактора базы.

<Style TargetType="local:Editor"> 
    <Setter Property="LabelWidth" Value="200" /> 
    <Setter Property="LabelHeight" Value="25" /> 
    <Setter Property="EditorHeight" Value="25" /> 
    <Setter Property="EditorWidth" Value="200" /> 
    <Setter Property="LabelColor" Value="Black" /> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="local:Editor"> 
       <Border Background="{TemplateBinding Background}" 
         BorderBrush="{TemplateBinding BorderBrush}" 
         BorderThickness="{TemplateBinding BorderThickness}"> 
        <Grid> 
         <Grid.ColumnDefinitions> 
          <ColumnDefinition Width="Auto" /> 
          <ColumnDefinition Width="Auto" /> 
         </Grid.ColumnDefinitions> 
         <TextBlock x:Name="PartLabel" 
            Text="{TemplateBinding Label}" 
            Width="{TemplateBinding LabelWidth}" 
            Height="{TemplateBinding LabelHeight}" 
            Style="{TemplateBinding LabelStyle}" 
            Foreground="{TemplateBinding LabelColor}" 
            VerticalAlignment="Center" /> 
         <ContentPresenter Grid.Column="1" 
              x:Name="PartEditor" 
              Height="{TemplateBinding EditorHeight}" 
              Width="{TemplateBinding EditorWidth}" 
              Style="{TemplateBinding EditorStyle}" 
              Content="{TemplateBinding EditorControl}" /> 
        </Grid> 
       </Border> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

Поэтому я создал свой первый пользовательский элемент управления, который расширил класс редактора.

[TemplatePart(Name = PartLabelName, Type = typeof (TextBlock))] 
[TemplatePart(Name = PartEditorName, Type = typeof (ContentPresenter))] 
public class NumericUpDownEditor : Editor 
{ 
    private ContentPresenter _partEditorControl; 
    private TextBlock _partLabel; 

    public NumericUpDownEditor() 
    { 
     DefaultStyleKey = typeof (NumericUpDownEditor); 
    } 

    public override void OnApplyTemplate() 
    { 
     base.OnApplyTemplate(); 
     _partLabel = GetTemplateChild(PartLabelName) as TextBlock; 
     _partEditorControl = GetTemplateChild(PartEditorName) as ContentPresenter; 

     if (_partLabel == null || _partEditorControl == null) 
     { 
      throw new NullReferenceException("Template parts are not available"); 
     } 
    } 
} 

И по умолчанию стиль

<Style TargetType="local:NumericUpDownEditor"> 
    <Setter Property="EditorControl"> 
     <Setter.Value> 
      <toolkit:NumericUpDown /> 
     </Setter.Value> 
    </Setter> 
</Style> 

Когда я использую этот NumericEditor в пользовательский элемент управления, ничего не отображает.

<StackPanel x:Name="LayoutRoot" Orientation="Vertical"> 
    <customControls:NumericUpDownEditor Label="Numeric Up" /> 
</StackPanel> 

Я только хочу установить редактор UIElement в каждом настраиваемом элементе управления, который я создаю. Нужно ли определять шаблон для NumericEditor в стиле? Или что еще я делаю неправильно?

Thank you

+0

То, что вы просили, непонятно. Вы можете уточнить? Какова ваша проблема? – rducom

+0

Я добавил скриншот и дополнительную информацию. Улучшает ли мой вопрос? – Ash

+0

Вы хотите обобщить пару «Ярлык» + «Редактируемая зона» в одном элементе управления? И использовать этот контроль везде? – rducom

ответ

0

Обнаружили ошибку. Я хотел бы удалить стиль по умолчанию из подклассифицированного элемента управления. И через этот answer узнал, что я бы объявить контроль часть редактора в стиле подкласса внутри ContentTemplate (DataTemplate), а не Content

Модифицированный стиль редактор и код класса

public static readonly DependencyProperty EditorControlTemplateProperty = DependencyProperty.Register(
     "EditorControlTemplate", typeof (DataTemplate), typeof (Editor), new PropertyMetadata(default(DataTemplate))); 

<ContentPresenter Grid.Column="1" x:Name="PartEditor" 
        Height="{TemplateBinding EditorHeight}" 
        Width="{TemplateBinding EditorWidth}" 
        Style="{TemplateBinding EditorStyle}" 
        Content="{TemplateBinding EditorControl}" 
        ContentTemplate="{TemplateBinding EditorControlTemplate}" /> 

Модифицированный Подкласс редактор

[TemplatePart(Name = PartLabelName, Type = typeof (TextBlock))] 
[TemplatePart(Name = PartEditorName, Type = typeof (ContentPresenter))] 
public class NumericUpDownEditor : Editor 
{ 
    public static readonly DependencyProperty ValueProperty = DependencyProperty.Register(
     "Value", typeof (double), typeof (NumericUpDownEditor), new PropertyMetadata(default(double))); 

    private ContentPresenter _partEditorControl; 
    private TextBlock _partLabel; 

    public double Value 
    { 
     get { return (double) GetValue(ValueProperty); } 
     set { SetValue(ValueProperty, value); } 
    } 

    public override void OnApplyTemplate() 
    { 
     base.OnApplyTemplate(); 
     _partLabel = GetTemplateChild(PartLabelName) as TextBlock; 
     _partEditorControl = GetTemplateChild(PartEditorName) as ContentPresenter; 

     if (_partLabel == null || _partEditorControl == null) 
     { 
      throw new NullReferenceException("Template parts are not available"); 
     } 
    } 
} 

И вот стиль для подкласса управления

<Style TargetType="local:NumericUpDownEditor"> 
    <Setter Property="EditorControlTemplate"> 
     <Setter.Value> 
      <DataTemplate> 
       <toolkit:NumericUpDown 
        Value="{Binding RelativeSource={RelativeSource AncestorType=local:NumericUpDownEditor}, Path=Value, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" /> 
      </DataTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 
Смежные вопросы