DataTemplate with TextBlock, ContentControl.ContentStringFormat is ignored - wpf

I have the following datatemplate
<DataTemplate x:Key="SectionHeader">
<Border CornerRadius="5">
<Border.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FF1E5270" Offset="1"/>
<GradientStop Color="#FF3E7595"/>
</LinearGradientBrush>
</Border.Background>
<TextBlock Text="{Binding}" FontSize="14" Foreground="White" Padding="0,5" HorizontalAlignment="Center" FontWeight="Bold" />
</Border>
</DataTemplate>
and I can use it as follows
<ContentControl Content="Summary" ContentTemplate="{StaticResource SectionHeader}" />
This works fine. But when I try to do the following
<ContentControl Content="{Binding SelectedOrder}" ContentStringFormat="Details for Order \{0\}" ContentTemplate="{StaticResource SectionHeader}" />
I do not get the the full string only the order number.
Is there a way to make this work with a single datatemplate or do I need to create a second data template?

See MSDN documentation on ContentControl.ContentStringFormat:
If you set the ContentTemplate or ContentTemplateSelector property of a ContentControl, the ContentStringFormat property is ignored.
Instead of relying on ContentStringFormat, you should either add StringFormat to your binding or create a trivial StringFormatConverter : IValueConverter and set binding's Converter and ConverterParameter properties, in case Binding.StringFormat doesn't work (it has non-obvious limitations too — it's used only when target property is of type String).
For example:
<Control.Resources>
<a:StringFormatConverter x:Key="StringFormatConverter"/>
</Control.Resources>
<!-- ... -->
<ContentControl
Content="{Binding SelectedOrder,
Converter={StaticResource StringFormatConverter},
ConverterParameter='Details for Order {0}'}"
ContentTemplate="{StaticResource SectionHeader}"/>
You can use this implementation of StringFormatConverter.

Related

binding the background color of a gradient inside of a WPF listbox datatemplate

So I have a datatemplate and there is board in it, here is what I wan to do.
<Border Grid.Column="0" Grid.Row="4" Grid.ColumnSpan="5">
<Border.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="Transparent"/>
<GradientStop
Color="{Binding Condition, Converter={StaticResourc ConditionTypeToColorConveter}}" Offset="0.541"/>
</LinearGradientBrush>
</Border.Background>
</Border>
I can see the converter being called no problem. but the color it returns isn't displayed. Now if I do this
<Border Grid.Column="0"
Grid.Row="4" Grid.ColumnSpan="5"
Background="{Binding Condition, Converter={StaticResourc ConditionTypeToColorConveter}}">
It works just fine - of course - I don't want it to be all one color I need it to be a gradient.
Anyone have any idea what is wrong with this? it's making me batty...
This can't work because in the first example you bind a Color in the second a Brush. What type your converter returns? You named it 'ToColor' but it is working as a Brush for Background.

Partial Text color update

Here is what i've
<StackPanel>
<TextBlock> abc </TextBlock>
<Textblock> def </Textblock>
<Textblock> ghi </Textblock>
</Stackpanel>
Now on GUI i show all three textblock's text in single line like : abcdefghi . I want to update the partial text color (irrespective of which textblock the textbelong.
Say i want to change the color of 40% of total text to red and other as white. (also the percentage amount is too variable) It will update by Binding. So no hardcoding for text % and any specific textblock.
Done by -.How to make text color appear differently using 2 textblock for a single text
You can do this with one TextBlock, a LinearGradient and a few attached properties, as long as you don't mind letters being partially colored.
EDIT: I decided to write a post showing the solution with attached properties, but in the meanwhile you could use simple XAML and bindings like so:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock FontSize="34" FontWeight="Bold"
Text="{Binding Value, ElementName=slider, StringFormat={}{0:p0} of this text is coloured}">
<TextBlock.Foreground>
<LinearGradientBrush EndPoint="1 0">
<GradientStop Color="BurlyWood" />
<GradientStop Color="BurlyWood" Offset="{Binding Value, ElementName=slider}" />
<GradientStop Color="Beige" Offset="{Binding Value, ElementName=slider}" />
<GradientStop Color="Beige" Offset="1" />
</LinearGradientBrush>
</TextBlock.Foreground>
</TextBlock>
<Slider x:Name="slider" Grid.Row="1" Minimum="0" Maximum="1" Value="0.4" />
</Grid>
And if you're interested by the solution using attached properties, you can visit Partially Coloured TextBlock on my blog.

Can you set a gradient brush for a listboxitem background in silverlight?

I am looking for a way to set a gradientbrush as the background for a listbox item. I have a DataTemplate defined and have specified a gradient brush but it always appears as the listbox background (i.e. it never shows as a gradient brush).
I have been able to set the background of the listbox itself, and I can set the listboxitem's background to a standard color using the "setter" object....but none of these are what I am after.
I really want the background on each list item to be a gradient brush.
Below is the datatemplate that I have constructed.
<ListBox Name="MyListBox" Margin="12,67,12,169">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Height="51" VerticalAlignment="Bottom">
<Grid.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FFC9F4D0"/>
<GradientStop Color="#FF2AC12A" Offset="0.333"/>
<GradientStop Color="#FF35DE35" Offset="1"/>
</LinearGradientBrush>
</Grid.Background>
<Canvas >
<dataInput:Label Width="227" Foreground="Yellow" Canvas.Left="158" Canvas.Top="8" Content="{Binding Place}"/>
<dataInput:Label Width="146" Foreground="Yellow" Canvas.Left="8" Canvas.Top="8" Content="{Binding Date}"/>
<dataInput:Label Content="{Binding People}" Width="346" FontSize="9.333" Foreground="Black" Canvas.Left="166" Canvas.Top="28"/>
<!-- <dataInput:Label Width="45" Content="Accept" Foreground="White" Canvas.Left="8" Canvas.Top="28"/>
<dataInput:Label Width="45" Content="Decline" Foreground="White" Canvas.Left="57" Canvas.Top="28"/> -->
<dataInput:Label Content="SomeText" Width="101" FontSize="9.333" Foreground="White" Canvas.Left="389" Canvas.Top="10"/>
<Image Height="21" Width="21" Canvas.Left="500" Canvas.Top="8" Source="Green Button.png"/>
</Canvas>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Any Thoughts?
What is happening in your data template:
The background of the grid is being set to the color you need. However on top of this Grid, your Canvas is getting painted. Hence the linear gradient background is invisible.
How to correct this?
Set Canvas.Background={Binding}
For which ever control within the canvas that you wish to inherit the Grid.Background to, set that control's Background={Binding}
Sample Code:
</Grid.ColumnDefinitions>-->
<Canvas Background="{Binding}">
<TextBox Width="227" Canvas.Left="158" Canvas.Top="8" Foreground="Yellow" Text="{Binding Name}" Background="{Binding}"/>
<TextBox Width="146" Canvas.Left="8" Canvas.Top="8" Foreground="Yellow" Text="{Binding Language}" Background="{Binding}"/>
</Canvas>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Hope this helps!
What you are doing is correct its doesn't sets the background of your listbox, it sets the background of your listboxitem only. I think you couldn't figure it out.
To figure it out just give the margin to u r grid 5 and then see.What you are doing is correct its doesn't sets the background of your listbox, it sets the background of your listboxitem only. I think you couldn't figure it out.
To figure it out just give the margin to u r grid 5 and then see.

WPF Templates error - "Provide value on 'System.Windows.Baml2006.TypeConverterMarkupExtension' threw an exception."

I've just started experimenting with WPF templates vs. styles and I'm not sure what I'm doing wrong. The goal below is to alternate the colors of the options in the menu. The code works fine with just the , but when I copy and paste/rename it for the second segment of "MenuChoiceOdd" I get the following error:
> Provide value on 'System.Windows.Baml2006.TypeConverterMarkupExtension' threw an exception.
Sample of the code:
<Window x:Class="WpfApplication1.Template_Testing"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Template_Testing" Height="300" Width="300">
<Grid>
<Grid.Resources>
<ControlTemplate x:Key="MenuChoiceEven">
<Border BorderThickness="1" BorderBrush="#FF4A5D80">
<TextBlock Height="Auto" HorizontalAlignment="Stretch" Margin="0" Width="Auto" FontSize="14" Foreground="SlateGray" TextAlignment="Left" AllowDrop="True" Text="{Binding Path=Content, RelativeSource={RelativeSource TemplatedParent}}">
<TextBlock.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="White" Offset="0" />
<GradientStop Color="#FFC2CCDB" Offset="1" />
</LinearGradientBrush>
</TextBlock.Background>
</TextBlock>
</Border>
</ControlTemplate>
<ControlTemplate x:Key="MenuChoiceOdd">
<Border BorderThickness="1" BorderBrush="#FF4A5D80">
<TextBlock Height="Auto" HorizontalAlignment="Stretch" Margin="0" Width="Auto" FontSize="14" Foreground="SlateGray" TextAlignment="Left" AllowDrop="True" Text="{Binding Path=Content, RelativeSource={RelativeSource TemplatedParent}}">
<TextBlock.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="White" Offset="0" />
<GradientStop Color="##FFCBCBCB" Offset="1" />
</LinearGradientBrush>
</TextBlock.Background>
</TextBlock>
</Border>
</ControlTemplate>
</Grid.Resources>
<Border BorderBrush="SlateGray" BorderThickness="2" Margin="10" CornerRadius="10" Background="LightSteelBlue" Width="200">
<StackPanel Margin="4">
<TextBlock Height="Auto" HorizontalAlignment="Stretch" Margin="2,2,2,0" Name="MenuHeaderTextBlock" Text="TextBlock" Width="Auto" FontSize="16" Foreground="PaleGoldenrod" TextAlignment="Left" Padding="10" FontWeight="Bold"><TextBlock.Background><LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"><GradientStop Color="LightSlateGray" Offset="0" /><GradientStop Color="DarkSlateGray" Offset="1" /></LinearGradientBrush></TextBlock.Background></TextBlock>
<StackPanel Height="Auto" HorizontalAlignment="Stretch" Margin="2,0,2,0" Name="MenuChoicesStackPanel" VerticalAlignment="Top" Width="Auto">
<Button Template="{StaticResource MenuChoiceEven}" Content="Test Even menu element" />
<Button Template="{StaticResource MenuChoiceOdd}" Content="Test odd menu element" />
</StackPanel>
</StackPanel>
</Border>
</Grid>
</Window>
What am I doing wrong?
Oy it's Monday...
When I copied pasted the color string from another control it put two "##"s in the prefix here:
<GradientStop Color="##FFCBCBCB" Offset="1" />
Still a lousy error message.
Similarly to others - this horrific error message just meant I had a syntax error in my xaml:
<CheckBox Height="" IsChecked="{Binding IsChecked, Mode=TwoWay}" Width="80">
Notice I hadn't filled in the height value..
I had the same error caused by:
<Border Margin="5" BorderBrush="Black" BorderThickness="" Width="Auto"/>
fixed by putting a number in BorderThickness
In my case, I changed the project name. After I got this error. I re-selected the images and saw that I needed to change the resource name of images too.
<Image x:Name="imgSrc" Grid.Row="1" Source="/PREV%20-%20Filter;component/Images/Subtraktive%20Farbmischung%20%28Malen%20mit%20Wasserfarben%29.jpg" />
/PREV%20-%20Filter;component needs to be corrected to /DSP%20-%20Filter;component in my case.
Assigning Width="*" on Grid gave me the error, which looks weird at the first time, but all it is trying to say is that the markup couldn't be converted to actual type.
Unlike others, I had my XAML syntax correct.
<ImageBrush ImageSource="..\Images\previous_icon.png" />
This error started appearing when i changed my image - later realised i did change the image in my folder but forgot to Include it in my project .
Hence although XAML could show me the image in 'Desgn' View - I faced this exception # run time.
Silly one.
I had the same error when using Grey instead of Gray in my BorderBrush
<Setter Property="BorderBrush" Value="Grey"/>
instead of
<Setter Property="BorderBrush" Value="Gray"/>
Here is another instance of this error and how I resolved it.
This appears to have been caused by upgrading my project from VS2010 to VS2012 and VS2013. Not sure exactly why that would be an issue here, but I guess it is.
I developed a Visual Studio Wizard to automate the process of adding a project to our very large solution (300+ projects) as there are additional requirements for us developers to help maintain the project. I used WPF for the wizard and that worked well for VS2010. I upgraded the project to VS2012 and VS2013 and I started getting this error. Turns out that at some point the path to my icon and image files was screwed up. Once I corrected it - which I did directly within the XAML - I stopped getting the error.
In case you may need help referencing resources - this is the post I used to correct my issues: How to reference an icon resource file reference in XAML
I had the same when I forgot curly brackets:
<DataTrigger Binding="{Binding Path=IsWhiteboardShared}" Value="True">
<Setter Property="Background" Value="StaticResource AccentColorBlueBrush"/>
</DataTrigger>
I was tasked to fix a bug where a similar error message was being shown ad infinitum. When I found out that the following caused the issue, I was a little disappointed (Was expecting something more complex and catastrophic!):
<Style BasedOn="{StaticResource LinkButton}" TargetType="Button" >
where LinkButton should have been LinkButtonStyle.
I had the same error, but was using the wrong path for an image in the resources folder
I had this...
<controls:ImageButton Grid.Column="2" ImageButtonSource="Resources/close_normal.png"/>
but i needed this...
<controls:ImageButton Grid.Column="2" ImageButtonSource="../Resources/close_normal.png"/>
Had to add ../ at the start to go back one folder first
I had the same error when using 'OutBox' for this code:
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<materialDesign:PackIcon Kind="OutBox" Width="25" Height="25" VerticalAlignment="Center" Margin="5" Foreground="DodgerBlue"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
OutBox was Unknow Value so changed to 'StopCircle' then fixed...
This exact context of the exception seems to vary as others answers point out but generally it occurs when value in beetwen "" in XAML has some incorrect data in it.
I encounteted the error in the same circumstances as James and it helped me to look at what's inside of InnerException which contained the actual exception cause.

How to position UserControl in the parent canvas

I want to place this UserControl at Canvas.Left="168", Canvas.Top="213".
However, the control appears at a corner. What should I do?
If I put the values at the point of usage for this class, the values are returned as NaN
In that case how can I get the correct Left and Top Values?
Usage:
<Canvas x:Name="DesignerCanvas"
ClipToBounds="True"
SnapsToDevicePixels="True">
<Gr:BareNode />
</Canvas>
UserControl:
<UserControl x:Class="DiagramDesigner.BareNode"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid>
<ContentControl Width="50"
Height="50"
Padding="2"
Canvas.Left="168" Canvas.Top="213">
<Ellipse IsHitTestVisible="False" >
<Shape.Fill>
<RadialGradientBrush Center="0.2, 0.2" GradientOrigin="0.2, 0.2" RadiusX="0.8" RadiusY="0.8">
<GradientStop Color="LightBlue" Offset="0"/>
<GradientStop Color="Blue" Offset="0.9"/>
</RadialGradientBrush>
</Shape.Fill>
</Ellipse>
</ContentControl>
</Grid>
</UserControl>
I'm not sure if you tried this or not, but just from looking at the XAML it appears that you are trying to set the position of the user control inside the user control. That won't work. You need to put it where you use the user control
<Canvas x:Name="DesignerCanvas"
ClipToBounds="True"
SnapsToDevicePixels="True">
<Gr:BareNode Canvas.Left="168" Canvas.Top="213"/>
</Canvas>
Take the Canvas.Left="168" Canvas.Top="213" part out of the ContentControl declaration of inside the user control.

Resources