Styling Common WPF Controls

I am studying the creation of universal type controls. This is aimed at (reduced) generic support in WPF 4 and future Silverlight and will contain a hierarchy of common controls.

I have two questions:

  • Can you use style settings and template bindings for non-generic properties defined in a common control?
  • In Silverlight, is there a value that I can use for the default style keyword in the base class, which allows me to use the same style in (temporary) classes of a certain type? ( ComponentResourceKeyDoes not exist in Silverlight, so the setting described below does not work.)

The control general control below defines two test properties: not a common property Descriptionand a common property Data. The control sets DefaultStyleKeyin ComponentResourceKeyto control.

Here's how test management is defined:

public class GenericControl<T> : Control {
  static GenericControl( ) {
    DefaultStyleKeyProperty.OverrideMetadata(
      typeof(GenericControl<T>), new FrameworkPropertyMetadata(
        new ComponentResourceKey( typeof(Proxy), "GenericControl`1" )
      )
    );
  }

  public static readonly DependencyProperty DescriptionProperty =
    DependencyProperty.Register(
      "Description", typeof(string), typeof(GenericControl<T>),
      new PropertyMetadata( "Default Description" )
    );
  public static readonly DependencyProperty DataProperty =
    DependencyProperty.Register(
      "Data", typeof(T), typeof(GenericControl<T>),
      new PropertyMetadata( default(T) )
    );

  public string Description { get { ... } set { ... } }
  public T Data { get { ... } set { ... } }
}

Here is the style for the control in generic.xaml:

<Style x:Key="{ComponentResourceKey {x:Type local:Proxy}, GenericControl`1}">
  <Setter Property="Control.Template">
    <Setter.Value>
      <ControlTemplate TargetType="{x:Type Control}">
        <Border Background="{TemplateBinding Background}"
                BorderBrush="{TemplateBinding BorderBrush}"
                BorderThickness="{TemplateBinding BorderThickness}"">
          <StackPanel Orientation="Horizontal">
            <TextBlock Text="{Binding Description, 
                             RelativeSource={RelativeSource TemplatedParent}}" />
            <TextBlock Text="{Binding Data,
                             RelativeSource={RelativeSource TemplatedParent}}" />
          </StackPanel>
        </Border>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Style>

Here are some examples of how this test control will be declared in xaml:

<ListBox Name="list" ... />
<GenericControl x:TypeArguments="sys:Int32" Description="Count: "
               Data="{Binding Items.Count, ElementName=list}" />

<Slider Name="slider" ... />
<GenericControl x:TypeArguments="sys:Double" Description="Slider Value: "
               Data="{Binding Value, ElementName=slider}" />

With the current generics support in WPF 4, you cannot use an open generic type as the TargetTypeof a style or control template (doing so results in a "'GenericControl`1' TargetType does not match type of element 'GenericControl`1'." exception). This has two main consequences, as mentioned in question 1 above:

  • RelativeSource={RelativeSource TemplatedParent} TemplateBinding , .
  • Description, .

WPF : . AddOwner, "" , "ProxyType.Property" . , Silverlight AddOwner, , , , .

Aside: It looks like there is a regression in the xaml parsing behavior for types. Using VS2008, can use {x:Type local:GenericControl`1} to get the open type of the control, which used as the example type in the ComponentResourceKey. In VS2010 though, this results in the following error: "Character '`' was unexpected in string 'local:GenericControl`1'. Invalid XAML type name.", so changed it to use the proxy type instead.

+3
2

WPF Silverlight. Silverlight , WPF:

  • Shreedhar, "XAML ".
  • , TargetType="{x:Type local:GenericControl(x:Int32)}", , .
  • " " XamlReader , .
+2
  • , . xaml . , :
SliderInt32 -> BaseRange<T> -> BaseSliderControl

BaseSliderControl SliderInt32, BaseRange. BaseRange, SliderInt32.

  1. Silverlight , , . "BaseSliderControl" , .

GenericControl`1 .. , .

+1

Source: https://habr.com/ru/post/1726101/


All Articles