Partial Text color update - wpf

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.

Related

DataTemplate with TextBlock, ContentControl.ContentStringFormat is ignored

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.

Create semi-circle blur effect on a Grid

I want to develop a WindowsPhone 8 app with a home page like the fourth phone on this page. The one with a mountain.
You can see an image with two layers over it. My problem is that I don't know how to call that effect in English, and also, I don't know how to do it.
Maybe I will need to make three copies of my image: one untouched, a second one with, a blur effect? and a third one with a 'bigger' blur effect.
Or maybe, I have to add two Grids with some white background and with an opacity less than 100%.
How would you do it?
Your solution is just a good one, I would the samething, and I don't expect that application to be implementing something different, in détails I would do :
One Grid with High Blur on the background.
Another Grid with middle Blur on the front. I'll use an OpacityMask set to a RadialGradientBrush to create that ring effect just like in here : http://msdn.microsoft.com/en-us/library/bb979637(v=vs.95).aspx
And one lase Grid with no Blur in the Front of The previous Grid again with a OpacityMask also set to a RadialGradientBrush.
The three Grids will all have the same Background TileBrush, example :
The Result I've made :
Code :
<StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
<TextBlock Text="The effect you asked, with :" Style="{StaticResource PhoneTextNormalStyle}" Margin="12,0"/>
<TextBlock Text="That's Clapton" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
</StackPanel>
<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentPanel1" Grid.Row="1" Margin="12,0,12,0">
<Grid.Background>
<ImageBrush ImageSource="Eric_Clapton_Blur3.jpg" Stretch="UniformToFill"/>
</Grid.Background>
</Grid>
<Grid x:Name="ContentPanel2" Grid.Row="1" Margin="12,0,12,0">
<Grid.OpacityMask>
<RadialGradientBrush Center="0.5,0.5">
<RadialGradientBrush.RelativeTransform>
<CompositeTransform CenterY="0.5" CenterX="0.5" TranslateX="0.4" ScaleX="1.4"/>
</RadialGradientBrush.RelativeTransform>
<!-- This gradient stop is partially transparent. -->
<GradientStop Color="#00000000" Offset="1" />
<!-- This gradient stop is partially transparent. -->
<GradientStop Color="#20000000" Offset="0.741" />
<!-- This gradient stop is fully opaque. -->
<GradientStop Color="#FF000000" Offset="0.728" />
</RadialGradientBrush>
</Grid.OpacityMask>
<Grid.Background>
<ImageBrush ImageSource="Eric_Clapton_Blur2.jpg" Stretch="UniformToFill"/>
</Grid.Background>
</Grid>
<Grid x:Name="ContentPanel3" Grid.Row="1" Margin="12,0,12,0">
<Grid.OpacityMask>
<RadialGradientBrush Center="0.5,0.5">
<RadialGradientBrush.RelativeTransform>
<CompositeTransform CenterY="0.5" CenterX="0.5" TranslateX="0.4" ScaleY="0.6"/>
</RadialGradientBrush.RelativeTransform>
<!-- This gradient stop is partially transparent. -->
<GradientStop Color="#00000000" Offset="1" />
<!-- This gradient stop is partially transparent. -->
<GradientStop Color="#20000000" Offset="0.741" />
<!-- This gradient stop is fully opaque. -->
<GradientStop Color="#FF000000" Offset="0.728" />
</RadialGradientBrush>
</Grid.OpacityMask>
<Grid.Background>
<ImageBrush ImageSource="Eric_Clapton.jpg" Stretch="UniformToFill"/>
</Grid.Background>
</Grid>
I know I didn't do it with perfection, and I used terrible naming for the Elements, It's just I've just woke up, and didn't even take my breakfast, hope that helps.

How to set the back ground color of grid-column in wpf?

I have a wpf mvvm application.
And have a GRID with multiple columns
whats best way to set the back ground color of grid-column in wpf?
dabble125's answer was perfect but to give you a sample and to mention a note that it is important where to place your rectangle see the code:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<!-- this is not a good place for text block.
the text block is beneath the rectangle
so it would not be seen -->
<!--<TextBlock Grid.Column="1" Text="Some Text"/>-->
<Rectangle Grid.Column="1" Grid.RowSpan="1000">
<Rectangle.Fill>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FF83FF97" Offset="0" />
<GradientStop Color="White" Offset="1" />
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<TextBlock Grid.Column="1" Text="Some Text"/>
</Grid>
One way:
Create a rectangle and set its fill to the color of your choice.
Then set its Grid.RowSpan value to a large number or the number of rows you have.
Create a rectangle and set its fill to the color of your choice.
Only having :
<Rectangle
Grid.Column="1"
Fill="#e8ebf1" />
works for me.
The Grid.RowSpan of previous answers is actually useless, and the LinearGradientBrush demonstrated is over-complicated for what is asked.

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.

Image reflection in Silverlight 4

I am developing a product scrolling feature where products info( product image, Name, price)will be shown side by side horizontally. i need to show the image of the product and also its reflection. under the reflected image i need to show the Prod Name and its price.
The problem here is i dont want to show the complete reflected image.
the oputput should be something like this
Image Height-100%
Reflected Image Height-20%
Product name
Product Price
The above pattern will repeat horizontally.
I am able to get the desired output with some problem. The reflected image is shown up with hieght 100% and the sapce between the actual image and product name is very high.
My reflected image should be a rotated image of the actual image and only half part of the actual image should be shown.
Sample Code so far..
<ListBox Name="testing" >
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate >
<DataTemplate>
<StackPanel Orientation="Vertical" VerticalAlignment="Center" HorizontalAlignment="Center" >
<Image Source="{Binding ImageUrl}" Width="200"/>
<Image Source="{Binding ImageUrl}" Width="200" RenderTransformOrigin="0.5,0.5" Opacity="0.3">
<Image.RenderTransform>
<ScaleTransform ScaleY="-1" ScaleX="1"></ScaleTransform>
</Image.RenderTransform>
<Image.OpacityMask>
<LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
<GradientStop Color="#00000000" Offset="0.5"/>
<GradientStop Color="#FFFFFFFF" Offset="1.0"/>
</LinearGradientBrush>
</Image.OpacityMask>
</Image>
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding Name}" HorizontalAlignment="Center" />
<TextBlock Text="{Binding Price}" HorizontalAlignment="Center"/>
</StackPanel>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Any pointers even is highly appreciated
For your scale transform, instead of -1, you may want to use a value like .2 since you want it to be 20% the height of the object.
As Jeff points out in order to compress the reflected image to 20% of the originals height you need a ScaleTransform with a ScaleY value of -0.2. The problem is that Render Transforms occur after the layout slot for the element as been allocated. Hence just setting you existing ScaleY value just leaves a 20% height image floating in middle of the same 100% space that the un-transformed image needs.
The Silverlight Toolkit LayoutTransformer control is designed to allow transforms to be applied to content before the layout slot for the control has been allocated. It can then inform its container of the actual space needed post transform.
With this control available change your second (reflected) image element to this:-
<toolkit:LayoutTransformer >
<toolkit:LayoutTransformer.LayoutTransform>
<ScaleTransform ScaleY="-0.2" ScaleX="1" />
</toolkit:LayoutTransformer.LayoutTransform>
<Image Source="Test.png" Width="200" Opacity="0.9">
<Image.OpacityMask>
<LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
<GradientStop Color="#00000000" Offset="0.1"/>
<GradientStop Color="#FFFFFFFF" Offset="1.0"/>
</LinearGradientBrush>
</Image.OpacityMask>
</Image>
</toolkit:LayoutTransformer>
I've tweaked some of the opacity values to make the effect more visible. Now the LayoutTransformer is performing the 20% scale and then reporting to the containing StackPanel the appropriately reduced height requirements.

Resources