I'm desperatly triying to bound an image (which is located in a subdirectory of application installation directory). I'm Using MVVM and .Net 3.5, is'ts easy to find the image path and return either a String, an Uri or a Bitmap in a property and use it in the xaml.
I tryied all these three formats to bind to UriSource in Images.Resources, but none of them worked. I tried also to bound the UriSource with a String property with a Converter, no luck!
No image is displayed.
Is it possible to achieve that ? Then what am I missing ?
xaml:
<TreeView ItemsSource="{Binding ObCol_FamilyTree}">
<i:Interaction.Behaviors>
<behaviours:BindableTreeViewSelectedItemBehavior SelectedItem="{Binding TreeViewSelectedItem, Mode=TwoWay}" />
</i:Interaction.Behaviors>
<TreeView.Resources>
<Style x:Key="ExpandingImageStyle" TargetType="{x:Type Image}">
<Setter Property="Source" Value="{DynamicResource Icon_Closed}"/>
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=TreeViewItem}, Path=IsExpanded}" Value="True">
<Setter Property="Source" Value="{DynamicResource Icon_Open}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TreeView.Resources>
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" />
<Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}"/>
</Style>
</TreeView.ItemContainerStyle>
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding ObCol_Items}">
<StackPanel Orientation="Horizontal">
<Image Width="16" Height="16" Margin="0,0,3,0" Style="{StaticResource ExpandingImageStyle}">
<Image.Resources>
<BitmapImage x:Key="Icon_Closed" UriSource="{Binding OpenFolderPath, Converter={StaticResource UriConverter}}"/>
<BitmapImage x:Key="Icon_Open" UriSource="{Binding OpenFolderPath, Converter={StaticResource UriConverter}}" />
</Image.Resources>
</Image>
<TextBlock Text="{Binding Name}" />
</StackPanel>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
Viewmodel :
private string myOpenFolderPath;
public ItemListVM()
{
myOpenFolderPath = AppDomain.CurrentDomain.BaseDirectory @"..\images\Icon_Open.png";
if (!File.Exists(myOpenFolderPath))
myOpenFolderPath = String.Empty;
}
public string OpenFolderPath
{
get { return Path.GetFullPath(myOpenFolderPath); }
}
Converter :
public class UriConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return new Uri(value.ToString());
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotSupportedException();
}
}
I tried the same with an Uri Property with a right Converter which is returning an Uri, no more luck!
EDIT : here is the solution:
<TreeView ItemsSource="{Binding ObCol_FamilyTree}">
<i:Interaction.Behaviors>
<behaviours:BindableTreeViewSelectedItemBehavior SelectedItem="{Binding TreeViewSelectedItem, Mode=TwoWay}" />
</i:Interaction.Behaviors>
<TreeView.Resources>
<Style x:Key="ExpandingImageStyle" TargetType="{x:Type Image}">
<Setter Property="Source" Value="{Binding DataContext.ClosedFolderPath, RelativeSource={RelativeSource AncestorType=TreeView}}"/>
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=TreeViewItem}, Path=IsExpanded}" Value="True">
<Setter Property="Source" Value="{Binding DataContext.OpenFolderPath, RelativeSource={RelativeSource AncestorType=TreeView}}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TreeView.Resources>
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" />
<Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}"/>
</Style>
</TreeView.ItemContainerStyle>
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding ObCol_Items}">
<StackPanel Orientation="Horizontal">
<Image Width="16" Height="16" Margin="0,0,3,0" Style="{StaticResource ExpandingImageStyle}"/>
<TextBlock Text="{Binding Name}" />
</StackPanel>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
CodePudding user response:
Neither a BitmapImage resource nor a Binding Converter is needed.
This works out of the box, due to built-in type conversion from string
to
ImageSource
:
<Setter Property="Source" Value="{Binding OpenedFolderPath}"/>
In the ItemTemplate of the TreeView this Binding will not work, because it doesn't have the expected DataContext. You would write
<Setter Property="Source"
Value="{Binding DataContext.OpenedFolderPath,
RelativeSource={RelativeSource AncestorType=TreeView}}"/>
Besides that, a converter for the UriSource
property of a BitmapImage would have to return an Uri, not another BitmapImage:
public object Convert(
object value, Type targetType, object parameter, CultureInfo culture)
{
return new Uri(value.ToString());
}