2016-07-18 31 views
1

テキストボックスに画像を表示するためのテンプレートを実装しましたが、画像を動的に表示できないという問題がありました。ここに私のコードはここwpfのテキストボックステンプレートに画像を動的に割り当て

Window.xaml

<TextBox Style="{StaticResource imageTextBox}" /> 

である私のテキストボックステンプレートは、あなたが<Image.Source>プロパティに{Binding}を使用することができます

<Style TargetType="Control" x:Key="imageTextBox"> 
    <Setter Property="Margin" Value="0,0,0,8"/> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="Control"> 
       <Border x:Name="bg" BorderThickness="1" CornerRadius="3" BorderBrush="Gray"> 
        <Grid> 
         <Grid.ColumnDefinitions> 
          <ColumnDefinition Width="30"/> 
          <ColumnDefinition Width="*"/> 
         </Grid.ColumnDefinitions> 
         <TextBox Style="{DynamicResource BasicTextBox}" Grid.Column="1" 
           Foreground="{TemplateBinding Foreground}" 
           Background="{TemplateBinding Background}" 
           FontFamily="{TemplateBinding FontFamily}" 
           FontSize="{TemplateBinding FontSize}" 
           FontWeight="{TemplateBinding FontWeight}" 
           MinWidth="340" Margin="1" /> 
         <Image Source="Images/img_1.gif" Width="20"/> 
        </Grid> 
       </Border> 

       <ControlTemplate.Triggers> 
        <Trigger Property="IsMouseOver" Value="True"> 
         <Setter Property="BorderBrush" TargetName="bg" Value="Black"/> 
        </Trigger> 
        <Trigger Property="IsFocused" Value="True"> 
         <Setter Property="BorderBrush" TargetName="bg" Value="Black"/> 
        </Trigger> 
       </ControlTemplate.Triggers> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

<Style x:Key="BasicTextBox" TargetType="{x:Type TextBox}"> 
    <Setter Property="VerticalContentAlignment" Value="Center"/> 
    <Setter Property="BorderThickness" Value="0"/> 
</Style> 
+0

あなたは*動的に画像を表示できません*で何を意味するのですか? – lokusking

+0

スタイルでは静的なパスをImage要素に割り当てていましたので、windows.xamlのテキストボックスにキーを割り当てるたびに、すべてのテキストボックスに単一のイメージが表示されます。異なるテキストボックスに対しては別のイメージを表示する必要があります。どのように実装することができますか? –

+0

カスタムコントロールのプロパティを追加し、イメージソースにバインドします。 – ViVi

答えて

3

です。ここでexample as a LinqPad queryget LinqPad free)です:

void Main() 
{ 
    // Need to parse XAML since LinqPad doesn't have an integrated XAML build 
    var xaml = @" 
    <Grid xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"" xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml""> 
    <Grid.Resources> 
    <Style TargetType=""Control"" x:Key=""imageTextBox""> 
     <Setter Property=""Margin"" Value=""0,0,0,8""/> 
     <Setter Property=""Template""> 
      <Setter.Value> 
       <ControlTemplate TargetType=""Control""> 
        <Border x:Name=""bg"" BorderThickness=""1"" CornerRadius=""3"" BorderBrush=""Gray""> 
         <Grid> 
          <Grid.ColumnDefinitions> 
           <ColumnDefinition Width=""30""/> 
           <ColumnDefinition Width=""*""/> 
          </Grid.ColumnDefinitions> 
          <TextBox Style=""{DynamicResource BasicTextBox}"" Grid.Column=""1"" 
            Foreground=""{TemplateBinding Foreground}"" 
            Background=""{TemplateBinding Background}"" 
            FontFamily=""{TemplateBinding FontFamily}"" 
            FontSize=""{TemplateBinding FontSize}"" 
            FontWeight=""{TemplateBinding FontWeight}"" 
            MinWidth=""340"" Margin=""1"" /> 
          <Image Source=""{Binding Image}"" Width=""20""/> 
         </Grid> 
        </Border> 

        <ControlTemplate.Triggers> 
         <Trigger Property=""IsMouseOver"" Value=""True""> 
          <Setter Property=""BorderBrush"" TargetName=""bg"" Value=""Black""/> 
         </Trigger> 
         <Trigger Property=""IsFocused"" Value=""True""> 
          <Setter Property=""BorderBrush"" TargetName=""bg"" Value=""Black""/> 
         </Trigger> 
        </ControlTemplate.Triggers> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 
    </Grid.Resources> 
    <TextBox Style=""{StaticResource imageTextBox}"" /> 
    </Grid> 
    "; 

    // Get some images... these could be in your resources 
    var png = PngBitmapDecoder.Create(new Uri("https://upload.wikimedia.org/wikipedia/commons/9/97/Esperanto_star.png"), BitmapCreateOptions.None, BitmapCacheOption.Default); 
    var vm = new ViewModel { Image = png.Frames[0] }; 
    var o = (FrameworkElement)XamlReader.Parse(xaml); 
    // Set the image source - in this case, a view model 
    o.DataContext = vm; 
    // Let LinqPad display it 
    PanelManager.DisplayWpfElement(o); 

    // This code is for the example only, to change the image after 2 seconds. 
    var dispatcher = o.Dispatcher; 
    Task.Run(async() => 
    { 
     await Task.Delay(2000); 
     await dispatcher.BeginInvoke((Action)(() => 
     { 
      png = PngBitmapDecoder.Create(new Uri("https://upload.wikimedia.org/wikipedia/commons/f/f6/Lol_question_mark.png"), BitmapCreateOptions.None, BitmapCacheOption.Default); 
      vm.Image = png.Frames[0]; 
     })); 
    }); 
} 

// Define other methods and classes here 
public class ViewModel : INotifyPropertyChanged 
{ 
    private ImageSource _image; 
    public event PropertyChangedEventHandler PropertyChanged; 

    public ImageSource Image 
    { 
     get 
     { 
      return _image; 
     } 
     set 
     { 
      if (_image == value) 
      { 
       return; 
      } 

      _image = value; 
      PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Image))); 
     } 
    } 
} 

この例ではBindingソースのような単純なビューモデルを使用していますが、それは任意の源である可能性があります。実際に更新することを示すために、2秒遅れてImageの値を変更するコードもあります。あなたのコードでは、これを省略し、それを更新する方法を使います。

最初はそれが表示されます。 First appearance of image

を次に更新した後: After update appearance

+1

ありがとうございます。本当に役に立ちました。 –

関連する問題