2017-04-05 4 views
2

Ich habe ein DrawingImage, das ich als Vektorbildplatzhalter verwende. Weiter gibt es Stile, die das jeweilige DrawingImage verwenden und es als Bild in meiner benutzerdefinierten UserControl-Schaltfläche verwenden.Bindung an generisches UI-Element/XAML-Schnittstelle

Bisher war alles in Ordnung, aber ich kam gerade zu der Erkenntnis, dass mein aktueller Ansatz dazu geführt hat, dass meine DrawingImages nicht wiederverwendbar sind, da sie ihre Brush-Eigenschaft fest an das Steuerelement gebunden haben, wie folgt :

<DrawingImage x:Key="addIcon"> 
     <DrawingImage.Drawing> 
      <DrawingGroup> 
       <GeometryDrawing Brush="{Binding Path=ImageBrush, ElementName=addButton}" Geometry="M438.2,0H51.6C23.1,0,0,23.2,0,51.6v386.6c0,28.5,23.2,51.6,51.6,51.6h386.6c28.5,0,51.6-23.2,51.6-51.6V51.6 
        C489.8,23.2,466.6,0,438.2,0z M465.3,438.2c0,14.9-12.2,27.1-27.1,27.1H51.6c-14.9,0-27.1-12.2-27.1-27.1V51.6 
        c0-14.9,12.2-27.1,27.1-27.1h386.6c14.9,0,27.1,12.2,27.1,27.1V438.2z" /> 
       <GeometryDrawing Brush="{Binding Path=ImageBrush, ElementName=addButton}" Geometry="M337.4,232.7h-80.3v-80.3c0-6.8-5.5-12.3-12.3-12.3s-12.3,5.5-12.3,12.3v80.3h-80.3c-6.8,0-12.3,5.5-12.3,12.2 
        c0,6.8,5.5,12.3,12.3,12.3h80.3v80.3c0,6.8,5.5,12.3,12.3,12.3s12.3-5.5,12.3-12.3v-80.3h80.3c6.8,0,12.3-5.5,12.3-12.3 
        C349.7,238.1,344.2,232.7,337.4,232.7z" /> 
      </DrawingGroup> 
     </DrawingImage.Drawing> 
    </DrawingImage> 

Nun, ich habe versucht, einen Weg zu kommen bis haben sie nicht direkt an das Element gebunden, sondern bis zu einem gewissen Art eines generischen Element (similairly als Schnittstellen arbeiten), so dass der Code wäre sicher dass alles, was daran gebunden ist, die Brush Dependency Eigenschaft hat.

Bisher konnte ich es nicht finden.

Ich habe auch versucht, durch einen Vorfahren, immer noch kein Glück zu suchen.

Gibt es eine mehr oder weniger gängige Praxis, an unbekannte Elemente zu binden, die bestimmte Abhängigkeitseigenschaften haben, ohne sie direkt zu exponieren?

Antwort

1

In der Tat gibt es keine Möglichkeit, direkt zu tun, was Sie fragen. Der Grund dafür ist, dass wenn Sie DrawingImage als Ressource definieren und dann als Quelle für das Image verwenden, keine Kopien der Ressource erstellt werden, sondern stattdessen jedes Bild dieselbe Ressource betrachtet. Daher kann die DrawingImage keine übergeordnete in der visuellen Struktur überhaupt haben, also gibt es einfach keine Kontrolle zu binden.

Hier gibt es zwei Möglichkeiten. Eine ist Verwenden Sie eine Geometry als Ressource, nicht DrawingImage. Dann können Sie einige DrawingImage Ressourcen erstellen, die auf diese Geometry verweisen und verschiedene Farben verwenden. Oder verwenden Sie nicht DrawingImage überhaupt, aber verwenden Sie die Geometrie direkt (z. B. durch die Path). Tatsächlich gibt es so viele Möglichkeiten, Geometrie-Ressourcen zu verwenden und zu kombinieren. Ich gebe nur einige Beispiele hier:

<Window x:Class="FlipControlApp.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     Title="MainWindow" Height="300" Width="300"> 
    <Window.Resources> 
     <PathGeometry x:Key="addIconGeometry" Figures="M337.4,232.7h-80.3v-80.3c0-6.8-5.5-12.3-12.3-12.3s-12.3,5.5-12.3,12.3v80.3h-80.3c-6.8,0-12.3,5.5-12.3,12.2 
       c0,6.8,5.5,12.3,12.3,12.3h80.3v80.3c0,6.8,5.5,12.3,12.3,12.3s12.3-5.5,12.3-12.3v-80.3h80.3c6.8,0,12.3-5.5,12.3-12.3 
       C349.7,238.1,344.2,232.7,337.4,232.7z"/> 

     <PathGeometry x:Key="iconBorderGeometry" Figures="M438.2,0H51.6C23.1,0,0,23.2,0,51.6v386.6c0,28.5,23.2,51.6,51.6,51.6h386.6c28.5,0,51.6-23.2,51.6-51.6V51.6 
       C489.8,23.2,466.6,0,438.2,0z M465.3,438.2c0,14.9-12.2,27.1-27.1,27.1H51.6c-14.9,0-27.1-12.2-27.1-27.1V51.6 
       c0-14.9,12.2-27.1,27.1-27.1h386.6c14.9,0,27.1,12.2,27.1,27.1V438.2z"/> 

     <GeometryGroup x:Key="addIconWithBorderGeometry"> 
      <StaticResource ResourceKey="iconBorderGeometry"/> 
      <StaticResource ResourceKey="addIconGeometry"/> 
     </GeometryGroup> 

     <DrawingImage x:Key="addIconBlack"> 
      <DrawingImage.Drawing> 
       <DrawingGroup> 
        <GeometryDrawing Brush="Black" Geometry="{StaticResource addIconWithBorderGeometry}" /> 
       </DrawingGroup> 
      </DrawingImage.Drawing> 
     </DrawingImage> 
    </Window.Resources> 

    <UniformGrid Columns="2"> 
     <Button Name="addButton0" Width="100" Height="100"> 
      <Image Source="{StaticResource addIconBlack}"/> 
     </Button> 

     <Button Width="100" Height="100" Foreground="Blue"> 
      <Image> 
       <Image.Source> 
        <DrawingImage> 
         <DrawingImage.Drawing> 
          <DrawingGroup> 
           <GeometryDrawing Brush="{Binding Foreground, RelativeSource={RelativeSource AncestorType=Control}}" 
               Geometry="{StaticResource addIconGeometry}" /> 
          </DrawingGroup> 
         </DrawingImage.Drawing> 
        </DrawingImage> 
       </Image.Source> 
      </Image> 
     </Button> 

     <Button Width="100" Height="100" Foreground="Green"> 
      <Grid> 
       <Path Data="{StaticResource iconBorderGeometry}" Fill="Pink" Stretch="Uniform"/> 
       <Path Data="{StaticResource addIconGeometry}" Fill="Purple" Stretch="Uniform" Margin="15"/> 
      </Grid> 
     </Button> 

     <Button x:Name="addBtn" Width="100" Height="100" Foreground="Green"> 
      <Path Fill="{Binding Foreground, ElementName=addBtn}" Stretch="Uniform"> 
       <Path.Data> 
        <CombinedGeometry Geometry1="{StaticResource iconBorderGeometry}" Geometry2="{StaticResource addIconGeometry}"/> 
       </Path.Data> 
      </Path> 
     </Button> 
    </UniformGrid> 
</Window> 

result

Eine weitere Möglichkeit ist Verwendung ganze Image als Ressource mit einem Brush an die einige Vorfahren Eigenschaft bindend. In diesem Fall muss jedoch das Attribut x:Shared verwendet werden. Daher muss die Ressource im kompilierten Ressourcenwörterbuch deklariert werden (Details siehe x:Shared).

Ressource erstellen:

<ResourceDictionary> 
    <Image x:Key="addIconImage2" x:Shared="False"> 
     <Image.Source> 
      <DrawingImage> 
       <DrawingImage.Drawing> 
        <DrawingGroup> 
         <GeometryDrawing Brush="{Binding Foreground, RelativeSource={RelativeSource AncestorType=Control}}" 
          Geometry="M438.2,0H51.6C23.1,0,0,23.2,0,51.6v386.6c0,28.5,23.2,51.6,51.6,51.6h386.6c28.5,0,51.6-23.2,51.6-51.6V51.6 
          C489.8,23.2,466.6,0,438.2,0z M465.3,438.2c0,14.9-12.2,27.1-27.1,27.1H51.6c-14.9,0-27.1-12.2-27.1-27.1V51.6 
          c0-14.9,12.2-27.1,27.1-27.1h386.6c14.9,0,27.1,12.2,27.1,27.1V438.2z" /> 
         <GeometryDrawing Brush="{Binding Foreground, RelativeSource={RelativeSource AncestorType=Control}}" 
          Geometry="M337.4,232.7h-80.3v-80.3c0-6.8-5.5-12.3-12.3-12.3s-12.3,5.5-12.3,12.3v80.3h-80.3c-6.8,0-12.3,5.5-12.3,12.2 
          c0,6.8,5.5,12.3,12.3,12.3h80.3v80.3c0,6.8,5.5,12.3,12.3,12.3s12.3-5.5,12.3-12.3v-80.3h80.3c6.8,0,12.3-5.5,12.3-12.3 
          C349.7,238.1,344.2,232.7,337.4,232.7z" /> 
        </DrawingGroup> 
       </DrawingImage.Drawing> 
      </DrawingImage> 
     </Image.Source> 
    </Image> 
</ResourceDictionary> 

dann verwenden:

<Button Name="addButton3" Width="100" Height="100" 
     Content="{StaticResource addIconImage}" Foreground="Red"/> 
<Button Name="addButton4" Width="100" Height="100" 
     Content="{StaticResource addIconImage}" Foreground="Green"/> 

Jedes Mal, wenn Sie darauf verweisen, werden neue Kopie erstellt werden.

Aber der erste Weg ist flexibler.

+0

Vielen Dank für die eingehende Erklärung. Wenn Sie Beispiele für den zweiten Teil hinzufügen könnten, wäre ich wirklich dankbar! –

+0

Das erklärt viel. Danke nochmal –