24

Ho creato un'immagine all'interno di ButtonStyle. Ora ho creato una proprietà associata in modo da poter impostare la sorgente per quell'immagine. Dovrebbe essere semplice ma sono bloccato con esso.Come utilizzare la proprietà associata in uno stile?

Questo è il mio ButtonStyle accorciata:

<Style x:Key="ToolBarButtonStyle" 
     TargetType="Button"> 
    ... 
    <Image x:Name="toolbarImage" 
      Source="{TemplateBinding PrismExt:ImageSourceAttachable:ImageSource}" 
      Width="48" 
      Height="48" /> 
    ... 
</Style> 

E questa è la definizione di proprietà allegato, noti che non ho idea di come risolvere il callback, come il DependencyProperty sembra essere il tasto invece dell'immagine. E Button non espone la mia immagine nel suo stile. È difficile.

namespace SalesContactManagement.Infrastructure.PrismExt 
{ 
    public class ImgSourceAttachable 
    { 
     public static void SetImgSource(DependencyObject obj, string imgSource) 
     { 
      obj.SetValue(ImgSourceProperty, imgSource); 
     } 

     public static string GetImgSource(DependencyObject obj) 
     { 
      return obj.GetValue(ImgSourceProperty).ToString(); 
     } 

     // Using a DependencyProperty as the backing store for MyProperty. This enables animation, styling, binding, etc... 
     public static readonly DependencyProperty ImgSourceProperty = 
      DependencyProperty.RegisterAttached("ImgSource", typeof(string), typeof(ImgSourceAttachable), new PropertyMetadata(Callback)); 

     private static void Callback(DependencyObject d, DependencyPropertyChangedEventArgs e) 
     { 
      //((Button)d).Source = new BitmapImage(new Uri(Application.Current.Host.Source, e.NewValue.ToString())); 
     } 
    } 
} 

Ecco come ho impostato la fonte immagine all'interno XAML:

<Button PrismExt:ImgSourceAttachable.ImgSource="./Images/New.png" 
     Style="{StaticResource ToolBarButtonStyle}" /> 

Tutte le idee per favore? Molte grazie,

+0

penso ho risposto al più presto qui, vuoi impostare la proprietà attraverso un setter e quindi associare ad esso all'interno del modello? –

+0

La vista rappresenta quattro pulsanti di una barra degli strumenti come questa: http://sl.venuscloud.com/ Mi piacerebbe iniettare il percorso dell'icona per ogni pulsante dalla vista nel modello attraverso la proprietà associata. Spero che questo lo renda più chiaro. Grazie – Houman

risposta

37

Ecco come è possibile impostare il proprietà associata in uno stile

<Style x:Key="ToolBarButtonStyle" TargetType="Button"> 
    <Setter Property="PrismExt:ImgSourceAttachable.ImgSource" 
      Value="./Images/New.png"/> 
    <!--...--> 
</Style> 

Quando vincolante per proprietà associate poi il percorso deve essere tra parentesi in modo da cercare di utilizzare RelativeSource Binding con TemplatedParent invece

<Setter Property="Template"> 
    <Setter.Value> 
     <ControlTemplate TargetType="Button"> 
      <Image x:Name="toolbarImage" 
        Source="{Binding RelativeSource={RelativeSource TemplatedParent}, 
            Path=(PrismExt:ImgSourceAttachable.ImgSource)}" 
        Width="48" 
        Height="48"> 
      </Image> 
     </ControlTemplate> 
    </Setter.Value> 
</Setter> 

Edit: Il codice precedente funziona in WPF, in Silverlight i Image spettacoli in fase di esecuzione, ma non riesce a t lui designer con un'eccezione. È possibile utilizzare il seguente codice nel PropertyChangedCallback per ottenere la Image come soluzione

private static void Callback(DependencyObject d, DependencyPropertyChangedEventArgs e) 
{ 
    Button button = d as Button; 
    Image image = GetVisualChild<Image>(button); 
    if (image == null) 
    { 
     RoutedEventHandler loadedEventHandler = null; 
     loadedEventHandler = (object sender, RoutedEventArgs ea) => 
     { 
      button.Loaded -= loadedEventHandler; 
      button.ApplyTemplate(); 
      image = GetVisualChild<Image>(button); 
      // Here you can use the image 
     }; 
     button.Loaded += loadedEventHandler; 
    } 
    else 
    { 
     // Here you can use the image 
    } 
} 
private static T GetVisualChild<T>(DependencyObject parent) where T : DependencyObject 
{ 
    T child = default(T); 

    int numVisuals = VisualTreeHelper.GetChildrenCount(parent); 
    for (int i = 0; i < numVisuals; i++) 
    { 
     DependencyObject v = (DependencyObject)VisualTreeHelper.GetChild(parent, i); 
     child = v as T; 
     if (child == null) 
     { 
      child = GetVisualChild<T>(v); 
     } 
     if (child != null) 
     { 
      break; 
     } 
    } 
    return child; 
} 
+0

Grazie. Questo codice viene compilato ora, tuttavia non vedo ancora le immagini. Sono abbastanza sicuro perché il CallBack di proprietà allegata è vuoto. Tuttavia, "DependencyObject d" contiene il pulsante stesso. Non capisco ... – Houman

+0

Ho appena notato che la tua domanda aveva entrambi i tag WPF e Silverlight, la mia risposta era per WPF. Ci proverò per Silverlight. –

+0

Hai ragione. scuse. Pensavo che per le proprietà attaccate non sarebbero state diverse. :) – Houman