2017-11-17 6 views
1

Ich habe ein benutzerdefiniertes Steuerelement, Kuchen, die zwei DependencyProperties namens Slice und Füllung enthält. Wie erstelle ich einen Stil, der mir Zugriff auf Slice gewährt, aber auch Slice erstellen kann?Habe meinen Kuchen und esse ihn auch: Binding a Container and It's Inhalt

<Style TargetType={x:Type local:Cake}> 
    //I don't like setting DataContext Here 
    <Setter Property="DataContext" Value="{Binding RelativeSource={RelativeSource Self}}/> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType={x:Type local:Cake}> 
       <Grid DataContext="{Binding RelativeSource={RelativeSource TemplatedParent}}">       

        //This is how I display a slice 
        <ContentPresenter Content={Binding Slice}/> 

        //This is how cake decorations are displayed 
        <ItemsPresenter/> 

       </Grid> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
    <Setter Property="Slice"> 
     <Setter.Value> 

      //Design Slice Here - it's easy to override when I want 
      <Slice Filling={Binding Filling}> // it's just in a setter. 

     </Setter.Value> 
    </Setter> 
    <Setter Property="DataContext" Value="{Binding RelativeSource={RelativeSource Self}}/> 
</Style> 

Optionen Ich habe versucht:

  • ich kein Usercontrol verwenden können, weil ich, mit dem Namen Inhalt zulassen möchten, die anscheinend nicht mit User Controls funktioniert. Siehe Here.

  • Ich weiß nicht wie das obige Beispiel, weil ich die Datacontext des Kuchenbehälter selbst gesetzt haben, einen Benutzer bedeutet nicht die Datacontext für ihre Bindungen verwenden können.

  • Ich kann die Filling-Eigenschaft nicht mit RelativeSource binden, da der Style mit mehreren Kuchen nicht wissen würde, welcher der richtige Elternteil war. Siehe Here.

  • ich den Inhalt Presenter direkt mit einem Slice-Elemente ersetzen könnte, sondern weil es in einer Vorlage ist, verliere ich Zugriff auf die Scheibe überall außerhalb der Vorlage. Während ich den VisualTree in die Scheibe tippen konnte, ist das ein Albtraum.

Access Slice from Cake Directly, but be able to edit it in xaml

Ich möchte im Grunde jeder Kuchen ein Stück haben, und in der Lage zu sein, es zu setzen

<Cake.Slice> 
    <DockPanel> 
     <Rectangle Background= “Blue”/> 
     <Rectangle Background= “Blue”/> 
     <Rectangle Background=“{Binding Filling}”/> 
    </DockPanel> 
</Cake.Slice> 

während es auch einen Standard-Look mit zu geben.

EDIT: Offenbar mein Stil funktioniert, vorausgesetzt, dass ich die Cake.dll Referenz wie auf dem Kuchen Projekt gegenüber. Warum sollte das sein?

+0

hast du ein bild was du in dem kuchen erreichen willst? –

+0

@AyyappanSubramanian Yep, nur eine hinzugefügt. – bwall

Antwort

1

Dies wird nicht genau das sein, was Sie brauchen, aber ich hoffe, es gibt Ihnen Hinweise, wie Sie das erreichen können.

Erstens brauchen Sie nicht DataContext an die Steuerung selbst festzulegen, Sie zu Eigenschaften auf dem Kuchen Kontrolle binden kann (Abfüll- und Slice) von Cake Control {TemplateBinding Slice} verwenden, die für {Binding Slice, RelativeSource={RelativeSource TemplatedParent}} nur eine Verknüpfung ist (so können Sie benutze das eine oder andere).

Dies ist eine vereinfachte Version Ihres Steuerelements, da ich nicht weiß, welche Elemente der ItemPresenter in Ihrem ControlTemplate enthalten sollte oder wie der Typ Ihrer Slice- und Filling-Eigenschaften ist. In diesem Beispiel ist Füllung SolidColorBrush und Slice ist ein Style. Dieser Stil wird auf ContentControl in Cakes ControlTemplate angewendet, sodass Sie vordefinierte Stile für Slices haben und die Füllung Ihrer Wahl anwenden können (wenn Ihre Slice-Eigenschaft einen anderen Zweck hat, können Sie eine andere Eigenschaft namens SliceStyle einführen).

Kuchen Kontrolle:

public class Cake : Control 
{ 
    static Cake() 
    { 
     DefaultStyleKeyProperty.OverrideMetadata(
      typeof(Cake), 
      new FrameworkPropertyMetadata(typeof(Cake))); 
    } 

    public SolidColorBrush Filling 
    { 
     get { return (SolidColorBrush)GetValue(FillingProperty); } 
     set { SetValue(FillingProperty, value); } 
    } 

    public static readonly DependencyProperty FillingProperty = 
     DependencyProperty.Register(
      "Filling", 
      typeof(SolidColorBrush), 
      typeof(Cake), 
      new PropertyMetadata(Brushes.Transparent)); 

    public Style Slice 
    { 
     get { return (Style)GetValue(SliceProperty); } 
     set { SetValue(SliceProperty, value); } 
    } 

    public static readonly DependencyProperty SliceProperty = 
     DependencyProperty.Register(
      "Slice", 
      typeof(Style), 
      typeof(Cake), 
      new PropertyMetadata(null)); 
} 

Standard-Style (generic.xaml):

<Style TargetType="{x:Type local:Cake}"> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="{x:Type local:Cake}"> 
       <ContentControl Width="{TemplateBinding Width}" 
           Height="{TemplateBinding Height}" 
           Style="{TemplateBinding Slice}"/> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

Verschiedene Scheibe Arten (diese Control für Content einstellen, so dass Sie das Problem Nummer 3 in nicht getroffen Ihre Frage):

<Window.Resources> 
    <Style x:Key="TwoLayeredSlice" TargetType="{x:Type ContentControl}"> 
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate> 
        <Grid> 
         <Grid.RowDefinitions> 
          <RowDefinition Height="*"/> 
          <RowDefinition Height="*"/> 
         </Grid.RowDefinitions> 
         <Rectangle Fill="{Binding Filling, 
          RelativeSource={RelativeSource AncestorType={x:Type local:Cake}}}"/> 
         <Rectangle Fill="Brown" 
            Grid.Row="1"/> 
        </Grid> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 

    <Style x:Key="FourLayeredSlice" TargetType="{x:Type ContentControl}"> 
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate> 
        <Grid> 
         <Grid.RowDefinitions> 
          <RowDefinition Height="*"/> 
          <RowDefinition Height="*"/> 
          <RowDefinition Height="*"/> 
          <RowDefinition Height="*"/> 
         </Grid.RowDefinitions> 
         <Rectangle Fill="{Binding Filling, 
          RelativeSource={RelativeSource AncestorType={x:Type local:Cake}}}"/> 
         <Rectangle Fill="Brown" 
            Grid.Row="1"/> 
         <Rectangle Fill="{Binding Filling, 
          RelativeSource={RelativeSource AncestorType={x:Type local:Cake}}}" 
            Grid.Row="2"/> 
         <Rectangle Fill="Brown" 
            Grid.Row="3"/> 
        </Grid> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 
</Window.Resources> 

und die Steuerung im Einsatz:

<Grid Background="Gray"> 
    <local:Cake Width="200" 
       Height="100" 
       HorizontalAlignment="Left" 
       Filling="Gold" 
       Slice="{StaticResource TwoLayeredSlice}"/> 
    <local:Cake Width="200" 
       Height="100" 
       HorizontalAlignment="Center" 
       Filling="Pink" 
       Slice="{StaticResource FourLayeredSlice}"/> 
    <local:Cake Width="200" 
       Height="100" 
       HorizontalAlignment="Right" 
       Filling="Blue" 
       Slice="{StaticResource FourLayeredSlice}"/> 
</Grid> 

Cakes

Guten Appetit!

+0

Während dies mir immer noch keinen direkten Zugriff auf die Scheibe gibt, macht es mir einen fantastischen Job, es mir zu ermöglichen, es zu entwerfen - danke, dass du eine Möglichkeit gefunden hast, RelativeSource zu benutzen! – bwall

Verwandte Themen