Declaring custom controls

2019-09-01 07:50发布

I'm going to use a bunch of controls that each consist of a label and a text box. Is it a good idea to declare a custom control so that in encapsulates both the caption of the label and the input area of the text box as one?

I can probably inherit and create something in C# but the point here is to get better at XAML so the approach of declaring such a thingy (not sure if it's called resource, template, style or anything else) by a markup is to be preferred (if not yet necessary).

At the moment, I went with the following approach but I'm not sure if I'm not creating more headache for myself in the future.

<StackPanel Grid.Row="0" Grid.Column="0">
  <Label Content="Boom" Style="{StaticResource DefaultInputStyle}" />
  <DatePicker Style="{StaticResource DefaultInputStyle}" />
</StackPanel>

The idea would be optimally to be able to use something like so.

At the moment, I went with the following approach but I'm not sure if I'm not creating more headache for myself in the future.

<MyCoolControl Grid.Row="0" Grid.Column="0"
               Content="Boom"
               Style="{StaticResource DefaultInputStyle}" />

1条回答
Summer. ? 凉城
2楼-- · 2019-09-01 08:41

I'm not sure if you can set DefaultInputStyle both for Label and for DatePicker. What is TargetType of DefaultInputStyle? Custom control is recommended in case that you will use this custom controle in more than one application. If you want to create custom control you need to inherit from control, create some dependency properties, override DefaultStyleKeyProperty.

public class MyCoolControl : Control
{
  public Style LabeStyle
  {
    get { return (Style)GetValue(LabeStyleProperty); }
    set { SetValue(LabeStyleProperty, value); }
  }

  public static readonly DependencyProperty LabeStyleProperty =
    DependencyProperty.Register(
      "LabeStyle", typeof(Style), typeof(MyCoolControl));

  public Style DatePickerStyle
  {
    get { return (Style)GetValue(DatePickerStyleProperty); }
    set { SetValue(DatePickerStyleProperty, value); }
  }

  public static readonly DependencyProperty DatePickerStyleProperty =
    DependencyProperty.Register(
      "DatePickerStyle", typeof(Style), typeof(MyCoolControl));

  public object LabelContent
  {
    get { return (object)GetValue(LabelContentProperty); }
    set { SetValue(LabelContentProperty, value); }
  }

  public static readonly DependencyProperty LabelContentProperty =
    DependencyProperty.Register(
      "LabelContent", typeof(object), 
      typeof(MyCoolControl), new PropertyMetadata(null));

  static MyCoolControl()
  {
    DefaultStyleKeyProperty.OverrideMetadata(
      typeof(MyCoolControl), 
      new FrameworkPropertyMetadata(typeof(MyCoolControl)));
  }
}

Define implicit style for MyCoolControl in Themes/Generic.xaml:

<Style TargetType="local:MyCoolControl">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate>
                <StackPanel>
                    <Label Content="{TemplateBinding LabelContent}" Style="{TemplateBinding LabeStyle}" />
                    <DatePicker Style="{TemplateBinding DatePickerStyle}" />
                </StackPanel>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Then you can use your custom control:

<local:MyCoolControl Grid.Row="0" Grid.Column="0"
           LabelContent="Boom" DatePickerStyle="{StaticResource DefaultInputDatePickerStyle}"
           LabelStyle="{StaticResource DefaultInputLabelStyle}" />
查看更多
登录 后发表回答