Laden...

ListBox Control erweitern

Erstellt von Ayke vor 13 Jahren Letzter Beitrag vor 13 Jahren 2.061 Views
Ayke Themenstarter:in
643 Beiträge seit 2006
vor 13 Jahren
ListBox Control erweitern

Ich möchte ein Control auf Basis der ListBox erstellen.

Im Codebehind lege ich eine Rounding- Eigenschaft fest.

    public partial class FilterView : ListBox
    {
        public static DependencyProperty RoundingProperty = DependencyProperty.Register("Rounding", typeof(CornerRadius), typeof(QueryFilterView), new PropertyMetadata(new CornerRadius(2)));
        public CornerRadius Rounding { get { return (CornerRadius)GetValue(RoundingProperty); } set { SetValue(RoundingProperty, value); } }

        public FilterView()
        {
            InitializeComponent();
        }
    }

Hier möchte ich beim ControlTemplate ein TemplateBinding benutzen um die Eigenschaft Rounding zu verwenden.

<ListBox     x:Class="UI.Controls.FilterView"
             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" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">

    <ListBox.Resources>
        <CornerRadius x:Key="CornerRadiusValue" BottomLeft="10"/>
        <Style TargetType="ctrl:FilterView">
            <Setter Property="BorderBrush" Value="Black"/>
            <Setter Property="BorderThickness" Value="1"/>
            <Setter Property="Background" Value="Transparent"/>
            <Setter Property="Rounding" Value="2"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate>
                        <Border BorderBrush="{TemplateBinding BorderBrush}"
                                BorderThickness="{TemplateBinding BorderThickness}" 
                                Background="{TemplateBinding Background}"
                                CornerRadius="{TemplateBinding Rounding}">
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </ListBox.Resources>
</ListBox>

Fehlermeldung:
Der statische Member "RoundingProperty" wurde nicht im Typ "Control" gefunden

Was mache ich falsch ?

U
1.578 Beiträge seit 2009
vor 13 Jahren

Die Fehlermeldung sagt es doch ganz deutlich. Er such das Property im "Control" objekt, aber das bringt dir ja nichts.
Dein "ControlTemplate" gibt kein TargetType an, also sucht er im fallback, das ist dann das Control.

> Das Style kennt dein FilterView Control nicht.

Wenn du ein Custom Control schreiben willst, dann mach das auch richtig.

  1. Erstelle eine Neue Klasse FilterView : ListBox (hast du schon)
  2. Gib der Klasse einen static ctor
static FilterView()
{
    DefaultStyleKeyProperty.OverrideMetadata(typeof(FilterView), new FrameworkPropertyMetadata(typeof(FilterView)));
}
  1. Erstelle ein Ordner "Themes" im Projekt
  2. In diesem Ordner erstelle ein "Generic.xaml" Resource dictionary
  3. In diesem Ordner machst du dein namespace bekannt
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                               xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                               xmlns:Controls="clr-namespace:UI.Controls">
  1. Und nun verleihst du dein Control sein aussehen
<Style TargetType="{x:Type Controls:FilterView}">
    <Setter Property="BorderBrush" Value="Black"/>
    <Setter Property="BorderThickness" Value="1"/>
    <Setter Property="Background" Value="Transparent"/>
    <Setter Property="Rounding" Value="2"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Controls:FilterView}">
                <Border BorderBrush="{TemplateBinding BorderBrush}"
                             BorderThickness="{TemplateBinding BorderThickness}"
                             Background="{TemplateBinding Background}"
                             CornerRadius="{TemplateBinding Rounding}">
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Nun kannst du das Control ganz normal verwenden wie du es von den normalen Controls kennst. Auch das Style brauchst du nicht angeben.

<Controls:FilterView Rounding="10">
<!-- ... -->
Ayke Themenstarter:in
643 Beiträge seit 2006
vor 13 Jahren

Danke mit den statischen constructor funktioniert es. Hab mir heute den teil zu WPF im openbook Visual C# 2010 durchgelesen. Irgenwie ist das ganz schön knapp gehalten. Wieso muss ich einen static constructor erstellen ? Wegen den DepencyProperties ?

U
1.578 Beiträge seit 2009
vor 13 Jahren

Nö, wegen dem OverrideMetadata
Da sagst du im prinzip "Schmeiß das alte Style von X weg und such es neu".

Dann sucht das .Net beim Applikationsstart nach den eingestellten Style im Themes Ordner "Aero.NormalColor.xaml" z.b. und wenn es das nicht findet nimmt er es aus der Generic.xaml als fallback.

So kannst du deinem Control native looks geben je nach Windows Theme (Classic, Luna, Aero).