In my WPF application I have a grid with a fixed set of SVG Images (I use SharpVectors library)
<Image Grid.Column="0" Grid.Row="0" Source="{svgc:SvgImage Source=Resources/0.svg}" Stretch="Fill"/>
<Image Grid.Column="1" Grid.Row="0" Source="{svgc:SvgImage Source=/Resources/1.svg}" Stretch="Fill"/>
<Image Grid.Column="2" Grid.Row="0" Source="{svgc:SvgImage Source=Resources/2.svg}" Stretch="Fill"/>
<Image Grid.Column="1" Grid.Row="0" Source="{svgc:SvgImage Source=/Resources/3.svg}" Stretch="Fill"/>
Now I want to have item control where I would bind a list of paths to the SVGs, something like this:
<ItemsControl DataContext="{Binding DataContext}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Image Stretch="Fill" Width="100" Height="100">
<Image.Source>
<renderers:SvgImageSource/> <!-- What should be used here as a path??? -->
</Image.Source>
</Image>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
But I don't get it how to use string path in the renderers:SvgImageSource tag.
Set an ItemsSource for your SVG image URIs. Then you can use the SvgImageConverter for binding.
<ItemsControl ItemsSource="{Binding YourSvgUriItems}">
<ItemsControl.Resources>
<svgc:SvgImageConverter x:Key="SvgImageConverter"/>
</ItemsControl.Resources>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Image Stretch="Fill" Width="100" Height="100"
Source="{Binding Converter={StaticResource SvgImageConverter}}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
You could try to bind to the path and use the SvgImageConverterExtension class:
<Image Stretch="Fill" Width="100" Height="100">
<Image.Source>
<Binding Path="YourUriProperty">
<Binding.Converter>
<converters:SvgImageConverterExtension />
</Binding.Converter>
</Binding>
</Image.Source>
</Image>
This is in code behind window
public WpfTestWindow()
{
InitializeComponent();
ComboboxCOLOR.ItemsSource = typeof(Colors).GetProperties();
}
This is the ComboBox
<ComboBox Name="ComboboxCOLOR" Height="25" Width="180">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Rectangle Fill="{Binding Name}" Width="16" Height="16"/>
<TextBlock Text="{Binding Name}" />
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
And - whatever color is chosen in ComboBox: It should fill up this Ellipse with that color;
Here below what I got at the moment, it doesnt work...
<Ellipse Fill="{Binding ComboboxCOLOR}" Name="Ellipse"
Margin="5" Height="40" Width="40"
Stroke="Black" StrokeThickness="5">
</Ellipse>
You can refer to the ComboBox using the ElementName in the binding.
Gets or sets the name of the element to use as the binding source object.
If you do not specify the element name, the binding markup extension will interpret ComboboxCOLOR as a property on the current data context of the Ellipse element. Then use the SelectedItem property and the Name property of the item as in your example to bind the Fill
<Ellipse Fill="{Binding SelectedItem.Name, ElementName=ComboboxCOLOR}" Name="Ellipse"
Margin="5" Height="40" Width="40"
Stroke="Black" StrokeThickness="5">
</Ellipse>
I'm using the following DataTemplate
<DataTemplate x:Key="platform_resources">
<StackPanel Orientation="Horizontal">
<Viewbox Width="30" Height="30" ToolTip="Network Domain Count" Stretch="Uniform">
<ContentControl DataContext="{Binding}" Focusable="False" Content="{DynamicResource appbar_server}" />
</Viewbox>
<TextBlock Margin="0,7,0,0" Text="{Binding Path=workload_count}"/>
<Separator Style="{StaticResource {x:Static ToolBar.SeparatorStyleKey}}" />
<Viewbox Width="30" Height="30" ToolTip="Logical Network Count" Stretch="Uniform">
<ContentControl Focusable="False" Content="{DynamicResource appbar_network_server_connecting}" />
</Viewbox>
<TextBlock Margin="0,7,0,0" Text="{Binding Path=vlan_count}"/>
<Separator Style="{StaticResource {x:Static ToolBar.SeparatorStyleKey}}" />
<Viewbox Width="30" Height="30" ToolTip="Network Domain Count" Stretch="Uniform">
<ContentControl Focusable="False" Content="{DynamicResource appbar_network}" />
</Viewbox>
<TextBlock Margin="0,7,0,0" Text="{Binding Path=networkdomain_count}"/>
</StackPanel>
</DataTemplate>
The template displays all the relevant data with separators but only shows the images on the last record. It's leaves spaces where the images are supposed to be, but no images.
Make sure you add x:Shared="False" property to your resources.
Example:
<Canvas x:Key="appbar_server" x:Shared="False">
<!-- ... -->
</Canvas>
This happens because you probably defined some Images (e.g appbar_server) in your resources and trying to display them in multiple items. But Image is a Visual and in WPF each Visual can only have one parent. So when your items are being generated, each item steals the Image from the previous one until the last item finally gets it.
Solution:
Unlike Image, BitmapImage is not a Visual and thus can be set multiple times as the source of different items. So instead of defining Images in your Resources, define BitmapImages:
<Window.Resources>
<BitmapImage x:Key="appbar_server" UriSource="C:\...\appbar_server.png"/>
....
And then instead of ContentControls create Image instances in your DataTemplate to present them:
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Viewbox Width="30" Height="30" ToolTip="Network Domain Count" Stretch="Uniform">
<Image Focusable="False" Source="{DynamicResource appbar_server}" />
</Viewbox>
<TextBlock Margin="0,7,0,0" Text="{Binding Path=workload_count}"/>
...
*Update:
The image is captured in a canvas which seems to be needing some
special wrapper to make this work.
In that case, you should define a DataTemplate for each Canvas like this:
<Window.Resources>
<DataTemplate x:Key="appbar_3d_3ds">
<Canvas Width="76" Height="76" Clip="F1 M 0,0L 76,0L 76,76L 0,76L 0,0">
<Path Width="32" Height="40" Canvas.Left="23" Canvas.Top="18" Stretch="Fill" Fill="Black" Data="F1 M 27,18L 23,26L 33,30L 24,38L 33,46L 23,50L 27,58L 45,58L 55,38L 45,18L 27,18 Z "/>
</Canvas>
</DataTemplate>
....
And then create ContentPresenter Instances in your ItemTemplate with their ContentTemplate set to your pre-defined data templates (e.g. appbar_3d_3ds).
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Viewbox Width="30" Height="30" ToolTip="Network Domain Count" Stretch="Uniform">
<ContentPresenter ContentTemplate="{DynamicResource appbar_3d_3ds}"/>
</Viewbox>
<TextBlock Margin="0,7,0,0" Text="{Binding Path=workload_count}"/>
....
Is it possible to make a datatemplate for ItemsControl, which would 'enlarge' selected item's content beyond ItemsControl height, overlapping other ItemsControl items - but without altering ItemsControl height/width, without shifting adjacent ItemsControl items.
I have interaction triggers and bindings etc, just need UI elements capable of that.
Tried Popup element - but it doesn't look to be the best solution.
EDIT:
Thanks again for your replies, I tried to post a simplier description of my problem - and that was my mistake, sorry. Heres the EXACT problem:
(tried to apply ScaleTransform - it makes my ScrollViewer larger)
<s:SurfaceScrollViewer MaxWidth="1920" Margin="50" ClipToBounds="False"
VerticalAlignment="Center" HorizontalAlignment="Center"
Visibility="{Binding Path=ScrollViewerYearVisibility}">
<ItemsControl HorizontalAlignment="Center" BorderBrush="Red" BorderThickness="3"
ItemsSource="{Binding Path=YearItemsSource}"
ItemTemplate="{StaticResource DataTemplateYearItem}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</s:SurfaceScrollViewer>
<DataTemplate x:Key="DataTemplateYearItem">
<Grid VerticalAlignment="Center" HorizontalAlignment="Center" ClipToBounds="False">
<Grid.InputBindings>
<MouseBinding MouseAction="LeftDoubleClick" Command="{Binding Path=CommandDeviceDoubleClick}"/>
</Grid.InputBindings>
<Image VerticalAlignment="Center" HorizontalAlignment="Center"
Width="200" Height="200" Stretch="None"
Source="{Binding Path=ContentImagePathCurrent}">
</Image>
<Image VerticalAlignment="Center" HorizontalAlignment="Center" ClipToBounds="False"
Margin="-248,-210,0,0"
Stretch="None"
Source="{Binding Path=SlideCurrent.ContentImagePath}">
<Image.RenderTransform>
<ScaleTransform ScaleX="3" ScaleY="3"/>
</Image.RenderTransform>
</Image>
</Grid>
</DataTemplate>
Can we able to create a MahApps Metro Master Animated Tab Control on to Metro Window title bar ?
I wrote a code like,
<Controls:MetroWindow.WindowCommands>
<Controls:WindowCommands HorizontalAlignment="Left">
<Grid HorizontalAlignment="Left">
<TabControl ItemsSource="{Binding Items1}" FontWeight="Thin" HorizontalAlignment="Left" HorizontalContentAlignment="Left">
<TabControl.ItemTemplate>
<DataTemplate>
<Grid>
<StackPanel Orientation="Horizontal">
<Rectangle Width="20" Height="10">
<Rectangle.Resources>
<SolidColorBrush x:Key="BlackBrush" Color="White"/>
</Rectangle.Resources>
<Rectangle.Fill>
<!--<VisualBrush Stretch="Fill" Visual="{StaticResource appbar_cupcake}" />-->
<ImageBrush Stretch="Fill" ImageSource="/Resources/Images/menu-home-off.png"></ImageBrush>
</Rectangle.Fill>
</Rectangle>
<TextBlock FontSize="14" FontWeight="Bold" Text="{Binding Name}"/>
</StackPanel>
</Grid>
</DataTemplate>
</TabControl.ItemTemplate>
<TabControl.ContentTemplate>
<DataTemplate>
<Label Margin="100 100 100 100" Content="{Binding Content}" Foreground="White" />
</DataTemplate>
</TabControl.ContentTemplate>
</TabControl>
</Grid>
</Controls:WindowCommands>
</Controls:MetroWindow.WindowCommands>
The Tab ItemTemplate is displaying in Title Window, The ContentTemplate is not displaying....
Is it possible?
If yes, How can i achieve this ?
Thanks in advance !!