2010-06-29 72 views
3

嗯,它不是非常动态的,至少它在运行时不会改变。根据内容动态地设置XAML图像源

这个想法是我有按钮,每个人都有一个独特的图像(图标32x32)。这些按钮都与我共用ControlTemplate的风格。因此,每当我将鼠标悬停时,每张图片也都有一种正常和另一种颜色。

我注意到,当我声明图像的源路径是他们几乎都是一样的,所以我虽然干(不要重复自己)。如果我可以使用按钮Name或某些其他属性作为源路径的一部分(即图像文件的名称),该怎么办?那将是很好的编程。

问题是我是新来的XAML,WPF或许编程在一起,所以我不知道该怎么做。我想这会需要后面的代码或者某种类型的转换器(猜想我会阅读关于转换器的更多信息)。下面是一些代码(这不工作,但它给你的总体思路(希望)):

<Style x:Key="ButtonPanelBigButton" TargetType="{x:Type Button}"> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="Button"> 
       <Border Name="ButtonBorder" 
         Height="78" 
         MaxWidth="70" 
         MinWidth="50" 
         BorderThickness="0.5" 
         BorderBrush="Transparent" 
         CornerRadius="8" > 
        <Grid> 
         <Grid.RowDefinitions> 
          <RowDefinition Height="2*" /> 
          <RowDefinition Height="*" /> 
         </Grid.RowDefinitions> 

         <!-- Here I wan't to put in the Name property of the button because there is a picture there to match --> 
         <Image x:Name="ButtonIcon" Source="..\Images\Icons\32x32\Blue\{Binding Name}.png" 

           Margin="4" 
           Height="32" 
           Width="32" 
           HorizontalAlignment="Center" 
           VerticalAlignment="Center" /> 

         <TextBlock Grid.Row="1" 
            Padding="5,2,5,2" 
            TextWrapping="Wrap" 
            Style="{StaticResource MenuText}" 
            HorizontalAlignment="Center" 
            VerticalAlignment="Center"> 
          <ContentPresenter ContentSource="Content" />     
         </TextBlock> 
        </Grid> 
       </Border> 

       <ControlTemplate.Triggers> 
        <Trigger Property="IsMouseOver" Value="True" > 
         <Setter TargetName="ButtonIcon" Property="Source" Value="..\Images\Icons\32x32\Green\user.png" /> <!-- Same Here --> 
         <Setter TargetName="ButtonBorder" Property="BorderBrush" Value="{StaticResource SecondColorBrush}" /> 
         <Setter TargetName="ButtonBorder" Property="Background"> 
          <Setter.Value> 
           <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1" Opacity="0.5"> 
            <GradientStop Color="{StaticResource MainColor}" Offset="1" /> 
            <GradientStop Color="{StaticResource SecondColor}" Offset="0.5" /> 
            <GradientStop Color="{StaticResource MainColor}" Offset="0" /> 
           </LinearGradientBrush> 
          </Setter.Value> 
         </Setter> 
        </Trigger> 
       </ControlTemplate.Triggers> 

      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

希望你在那里我有这个打算,有人也许能帮助我,所以我的代码很好,干(现在我重复自己!!!)。

回答

2

你是对的:解决这个问题的简单方法是使用转换器。

Source属性需要ImageSource,因此您需要自己在转换器中加载位图。

该转换器使用这样的:

<Image Source="{Binding Name, 
         RelativeSource={RelativeSource TemplatedParent}, 
         Converter={x:Static local:ImageSourceLoader.Instance}, 
         ConverterParameter=..\Images\Icons\32x32\Blue\{0}.png}" /> 

而实现这样的:

public class ImageSourceLoader : IValueConverter 
{ 
    public static ImageSourceLoader Instance = new ImageSourceLoader(); 

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
    var path = string.Format((string)parameter, value.ToString()); 
    return BitmapFrame.Create(new Uri(path, UriKind.RelativeOrAbsolute)); 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
    throw new NotImplementedException(); 
    } 
} 

注意,这个简单的解决方案不能处理相对URI,因为图像的基本URI属性是不可用到转换器。

<Image local:ImageHelper.SourcePath="{Binding Name, 
         RelativeSource={RelativeSource TemplatedParent}, 
         StringFormat=..\Images\Icons\32x32\Blue\{0}.png}" /> 

而且附加属性的PropertyChangedCallback的基本URI与URI格式化字符串合并后处理负荷的图像:

如果你想使用相对URI,您可以通过绑定的附加属性和使用的StringFormat做到这一点
public class ImageHelper : DependencyObject 
{ 
    public static string GetSourcePath(DependencyObject obj) { return (string)obj.GetValue(SourcePathProperty); } 
    public static void SetSourcePath(DependencyObject obj, string value) { obj.SetValue(SourcePathProperty, value); } 
    public static readonly DependencyProperty SourcePathProperty = DependencyProperty.RegisterAttached("SourcePath", typeof(string), typeof(ImageHelper), new PropertyMetadata 
    { 
    PropertyChangedCallback = (obj, e) => 
     { 
     ((Image)obj).Source = 
      BitmapFrame.Create(new Uri(((IUriContext)obj).BaseUri, (string)e.NewValue)); 
     } 
    }); 
} 
+0

确定试图让这个工作,但由于路径和{0} – 2010-06-30 09:51:17

+0

有字符串文字和标记扩展的问题OK的作品像一个魅力,必须改变一个属性,因为这样的文字StringFormat = {} .. \\图像\\图标\\ 32×32 \\绿\\ {0}} png格式” – 2010-06-30 10:34:36