2010-06-29 3 views
3

글쎄, 실제로 동적이지는 않습니다. 적어도 런타임에는 변경되지 않습니다.XAML 이미지 소스는 콘텐츠를 기반으로 동적으로 설정됩니다.

아이디어는 버튼이 있고 각 이미지에는 고유 한 이미지 (아이콘 32x32)가 있습니다. 버튼들은 모두 ControlTemplate을 엉망으로 만드는 스타일을 공유합니다. 그래서 각각의 이미지는 정상적인 것과 정상적인 것의 2 가지 색상을 가지고 있습니다.

내가 이미지의 소스 경로를 선언하면 거의 동일하므로 DRY (반복하지 말 것)라는 사실을 알게되었습니다. 원본 경로 (예 : 이미지 파일의 이름)의 일부로 버튼 이름이나 다른 속성을 사용할 수 있다면 어떨까요? 좋은 프로그래밍이 될 것입니다.

문제는 내가 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> 

가 잘하면 내가이 함께 갈거야 누군가가 그렇게 나를 도울 수있을 어디서 얻을 수를 내 코드는 멋지다. 그리고 DRY (지금 나는 스스로 반복하고있다 !!!).

답변

2

맞습니다.이 문제를 쉽게 해결할 수있는 방법은 변환기를 사용하는 것입니다.

Source 속성은 ImageSource를 사용하므로 변환기에서 비트 맵을 직접로드해야합니다.

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

및 구현 :

컨버터는 다음과 같이 사용됩니다 변환기로.

<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} –

+0

OK가 매력처럼 작동하므로 문자열 리터럴 및 마크 업 확장에 문제가있는 경우이 StringFormat = {} ..과 같은 리터럴 때문에 속성을 하나 변경해야합니다. \\ 이미지 \\ 아이콘 \\ 32x32 \\ 녹색 \\ {0} .png} " –

관련 문제