2017-10-26 1 views
2

Ich versuche eine benutzerdefinierte Klasse zu erstellen, die vom Image-Steuerelement geerbt wurde, und ich habe einige Probleme mit der Bindung.Verbinde eine DependancyProperty von einer Anwendungsressource mit einer Control DependancyProperty (die die Ressource verwendet)

ich DrawingImage in meinen Ressourcen verwende (das ist, was für das Vektor Bild geliefert wird)

so in meiner App.xaml Ressource Ich habe ein paar DrawingImages, Beispiel eins:

<DrawingImage x:Key="Shutdown"> 
      <DrawingImage.Drawing> 
       <DrawingGroup> 
        <DrawingGroup.Children> 
         <DrawingGroup> 
          <DrawingGroup.Children> 
           <GeometryDrawing Brush="{x:Null}"> 
            <GeometryDrawing.Pen> 
          Here--> <Pen Brush="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type local:IconImage}}, Path=Colour, UpdateSourceTrigger=PropertyChanged}" Thickness="2" /> 
            </GeometryDrawing.Pen> 
            <GeometryDrawing.Geometry> 
             <PathGeometry FillRule="Nonzero" Figures="M8.332,4.941C5.759,6.271 4,8.956 4,12.052 4,16.47 7.582,20.052 12,20.052 16.418,20.052 20,16.47 20,12.052 20,8.911 18.19,6.193 15.555,4.884" /> 
            </GeometryDrawing.Geometry> 
           </GeometryDrawing> 
         Here--> <GeometryDrawing Brush="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type local:IconImage}}, Path=Colour, UpdateSourceTrigger=PropertyChanged}" Pen="{x:Null}"> 
            <GeometryDrawing.Geometry> 
             <RectangleGeometry RadiusX="0" RadiusY="0" Rect="11,2,2,10" /> 
            </GeometryDrawing.Geometry> 
           </GeometryDrawing> 
          </DrawingGroup.Children> 
          <DrawingGroup.ClipGeometry> 
           <RectangleGeometry Rect="0,0,24,24" /> 
          </DrawingGroup.ClipGeometry> 
         </DrawingGroup> 
        </DrawingGroup.Children> 
       </DrawingGroup> 
      </DrawingImage.Drawing> 
     </DrawingImage> 

und ich habe meine eigene Klasse wie folgt aufgebaut:

public class IconImage : Image 
{ 
    public enum Icons 
    { 
     None, 
     Shutdown, 
     Minimize 
    } 

    private Icons _icon; 
    public Icons Icon 
    { 
     get { return _icon; } 
     set 
     { 
      _icon = value; 
      if (value == Icons.None) 
      { 
       Visibility = Visibility.Hidden; 
      } 
      else 
      { 
       Visibility = Visibility.Visible; 
       this.SetResourceReference(Image.SourceProperty, value.ToString()); 
      } 
     } 
    } 

    public static readonly DependencyProperty ColourProperty = DependencyProperty.Register("Colour", typeof(Brush), typeof(IconImage), new PropertyMetadata(Brushes.Black)); 

    public Brush Colour 
    { 
     get { return (Brush)GetValue(ColourProperty); } 
     set { SetValue(ColourProperty, value); } 
    } 
} 

Usasge:

<local:IconImage Icon="Shutdown" Colour="CornflowerBlue" /> 

Problem ist, dass meine Pinselbindungen in den DrawingImages nicht an meine Color DependancyProperty in der benutzerdefinierten Klasse gebunden sind und ich keine Ahnung habe, wie dies zu erreichen ist, oder, wenn es überhaupt möglich ist. Wenn ich die Pinsel fest codiere, funktioniert es perfekt (natürlich). Ich muss nur in der Lage sein, die Farbe von der Steuerung zur Designzeit oder jederzeit im Code dahinter zu ändern.

Vielen Dank im Voraus!

-Sean-

+0

Wo wurde 'DrawingImage' verwendet? Sicher, 'AncestorType' von' local: IconImage' für das 'DrawingImage'? – Iron

+0

Sie wird verwendet, wenn die Icon-Eigenschaft festgelegt ist: this.SetResourceReference (Image.SourceProperty, value.ToString()); das setzt es in diesem Fall auf die DynamicReference von "Shutdown". –

+0

Könnten Sie bitte den Code zeigen, der die Ressource 'x: Key =" Shutdown "' benutzt? – Iron

Antwort

0

Sie können es so funktioniert. Zuerst markieren Sie die Ressource als nicht freigegeben, weil Sie möchten, dass Ihr DrawingImage Aussehen ändert, basierend auf dem IconImage es Teil ist, was nicht viel Sinn macht für eine freigegebene Ressource (in diesem Fall bedeutet gemeinsam wie Singleton - nur eine globale Instanz):

<DrawingImage x:Key="Shutdown" x:Shared="False"> 
    <!-- the rest --> 
</DrawingImage> 

Dann anstelle SetResourceReference verwendet es wie folgt tun:

var resource = FindResource(value.ToString()); 
// alternative 
// var resource = Application.Current.Resources[value.ToString()]; 
this.Source = (ImageSource)resource;  

Dies wird das gleiche sein, etwa wie Ihr DrawingImage xAML direkt unter IconImage wie andere Antwort schlägt setzen.

Sie haben besser mehr eindeutige Namen für Ihre Ressourcen übrigens, um zufällige Verwendung von Ressourcen mit dem gleichen Namen in den Baum zu vermeiden (vor allem, wenn Sie FindResource verwenden).

+0

Das funktioniert! Vielen Dank! Ein kleines Problem, ich bekomme zur Design-Zeit nichts, es zeigt sich erst, wenn ich die Applikation starte. Irgendwelche Vorschläge dafür? –

+0

Was die einzigartigen Namen betrifft, werden sie viel einzigartiger sein und es gibt nur eine Handvoll von ihnen. Dies war nur ein Beispiel. –

+0

@SeanMakins gut oft ist es ziemlich schwierig zu machen WPF-Designer zeigen, was Sie wollen ... In diesem Fall findet und lädt Ressource gut, aber kann nicht aus irgendeinem Grund an Ihre 'Colour'-Eigenschaft binden. Sie können eine andere Instanz von Visual Studio anschließen, um dies zu debuggen, wenn Sie möchten. Als vorübergehende Lösung - bieten Sie einen Fallback-Wert für Ihre Bindungen: ' Evk

-1
<local:IconImage Icon="Shutdown" Colour="CornflowerBlue"> 
    <local:IconImage.Source> 
     <DrawingImage> 
      <DrawingImage.Drawing> 
       <DrawingGroup> 
        <DrawingGroup.Children> 
         <DrawingGroup> 
          <DrawingGroup.Children> 
           <GeometryDrawing Brush="{x:Null}"> 
            <GeometryDrawing.Pen> 
             <Pen Brush="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type local:IconImage}}, Path=Colour, UpdateSourceTrigger=PropertyChanged}" Thickness="2" /> 
            </GeometryDrawing.Pen> 
            <GeometryDrawing.Geometry> 
             <PathGeometry FillRule="Nonzero" Figures="M8.332,4.941C5.759,6.271 4,8.956 4,12.052 4,16.47 7.582,20.052 12,20.052 16.418,20.052 20,16.47 20,12.052 20,8.911 18.19,6.193 15.555,4.884" /> 
            </GeometryDrawing.Geometry> 
           </GeometryDrawing> 
           <GeometryDrawing Brush="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type local:IconImage}}, Path=Colour, UpdateSourceTrigger=PropertyChanged}" Pen="{x:Null}"> 
            <GeometryDrawing.Geometry> 
             <RectangleGeometry RadiusX="0" RadiusY="0" Rect="11,2,2,10" /> 
            </GeometryDrawing.Geometry> 
           </GeometryDrawing> 
          </DrawingGroup.Children> 
          <DrawingGroup.ClipGeometry> 
           <RectangleGeometry Rect="0,0,24,24" /> 
          </DrawingGroup.ClipGeometry> 
         </DrawingGroup> 
        </DrawingGroup.Children> 
       </DrawingGroup> 
      </DrawingImage.Drawing> 
     </DrawingImage> 
    </local:IconImage.Source> 
</local:IconImage> 
+0

Ich bin mir sicher, dass das funktionieren könnte, aber dies erlaubt mir nicht, die Quelle dynamisch zu setzen, ich möchte nicht jedesmal das gesamte DrawingImage angeben müssen, wenn ich dieses Steuerelement verwende. (Es wird viele Male benutzt) und manchmal ändert es sich während der Laufzeit, deshalb habe ich die Eigenschaft Icon. –

+0

Wie wäre es mit dem 'Icon'' DependencyProperty' und einem 'Style' für das' IconImage' zu ​​bekommen, was Sie wollen? – Iron

Verwandte Themen