I can't seem to find the solution to this strange problem. I have a Silverlight 3 toolkit Column chart that doesn't show all the columns. I have a data set of 10 columns and it only shows 7.
image of the graph:
<UserControl x:Class="graph.bd"
xmlns:DV="clr-namespace:System.Windows.Controls.DataVisualization;assembly=System.Windows.Controls.DataVisualization.Toolkit"
xmlns:DVC="clr-namespace:System.Windows.Controls.DataVisualization.Charting;assembly=System.Windows.Controls.DataVisualization.Toolkit">
<UserControl.Resources>
<Style x:Key="ColorByGradeColumn" TargetType="DVC:ColumnDataPoint">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="DVC:ColumnDataPoint">
<Border Background="{Binding ColColor}"
BorderBrush="{Binding ColColor}"
BorderThickness="0.5">
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<!-- canvases and other code goes here... -->
<DVC:Chart x:Name="Graphic" Width="350" Height="250" Background="Transparent">
<DVC:Chart.Series>
<DVC:ColumnSeries Title="Fras"
IndependentValueBinding="{Binding ColName}"
DependentValueBinding="{Binding ColValue}"
DataPointStyle="{StaticResource ColorByGradeColumn}"
>
<DVC:ColumnSeries.IndependentAxis>
<DVC:CategoryAxis Orientation="X">
<DVC:CategoryAxis.AxisLabelStyle>
<Style TargetType="DVC:AxisLabel">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="DVC:AxisLabel">
<Grid Width="70" ShowGridLines="True" Height="8" Background="Transparent"
HorizontalAlignment="Left" VerticalAlignment="Bottom">
<TextBlock x:Name="YAxisTitle" HorizontalAlignment="Center" VerticalAlignment="Center" Text="{Binding}" RenderTransformOrigin="0.5,0.5" FontSize="8">
<TextBlock.RenderTransform>
<RotateTransform Angle="270" CenterX="5"/>
</TextBlock.RenderTransform>
</TextBlock>
<Grid.RenderTransform>
<RotateTransform Angle="60" ></RotateTransform>
</Grid.RenderTransform>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</DVC:CategoryAxis.AxisLabelStyle>
</DVC:CategoryAxis>
</DVC:ColumnSeries.IndependentAxis>
</DVC:ColumnSeries>
</DVC:Chart.Series>
<DVC:Chart.PlotAreaStyle>
<Style TargetType="Grid">
<Setter Property="Background" Value="Black" />
</Style>
</DVC:Chart.PlotAreaStyle>
<DVC:Chart.LegendStyle>
<Style TargetType="DV:Legend">
<Setter Property="Width" Value="0"/>
<Setter Property="Height" Value="0"/>
</Style>
</DVC:Chart.LegendStyle>
<DVC:Chart.Foreground>
<SolidColorBrush Color="White"></SolidColorBrush>
</DVC:Chart.Foreground>
</DVC:Chart>
My data set is made of just 3 values: the main number which is an integer and is how high the column is, and a name for the columns which is a string and I can't show in the picture, as well as a color for the columns which binds on the style and can change on the code behind.
I also can't upgrade to silverlight 4 or higher because this page with the columns is embebed in another page which runs only on silverlight 3
EDIT: I actually have another 3 graphs in the page which work without problems, only this one is having issues. all four have the exact same code in the .xaml (obviously with different x:name) and all 4 have very similar code in the xaml.cs. Please someone help, I really need to get this issue fixed. I can provide more code if needed.
EDIT2:
I think what is happening is one of the columns is getting behind or on top of the others, but I don't understand why. None of the other graphs has this issue.
Okay, so I found out what was wrong. It turns out it was the data, one of the 10 rows that are loaded had the same value on the column that is the X axis but diffent Y value, so the chart was displaying both columns as one.
I am quite embarrassed, but I hope this will help someone out one day.
Related
I want to add conditionnal formatting (just font color) to the textbox part of a combobox. According to MSDN, it's the "PART_EditableTextBox" element. A quick search on SO got me started but I now face a problem: it overrides the whole template. According to this SO answer, I can use "BasedOn" to override only specific properties but I've no idea how/where to use it.
This is my current template:
<ControlTemplate x:Key="MyComboBoxTextBox" TargetType="ComboBox" <!--Here?--> >
<TextBox x:Name="PART_EditableTextBox" <!--Maybe Here?-->>
<TextBox.Style>
<Style TargetType="TextBox">
<Style.Triggers>
<Trigger Property="Text" Value="MAL">
<Setter Property="Foreground" Value="DarkOrange"></Setter>
</Trigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
</ControlTemplate>
It works, I can still type in valid values and "MAL" does make the text orange but there's no dropdown anymore.
On MSDN, I found the following:
<TextBox x:Name="PART_EditableTextBox"
Style="{x:Null}"
Template="{StaticResource ComboBoxTextBox}"
HorizontalAlignment="Left"
VerticalAlignment="Bottom"
Margin="3,3,23,3"
Focusable="True"
Background="Transparent"
Visibility="Hidden"
IsReadOnly="{TemplateBinding IsReadOnly}" />
I suppose I should base my template on this "ComboBoxTextBox" but I don't know how to reference it. Do I really need to copy the whole template or is there a way to override a specific property?
EDIT:
On the same MSDN page comboboxTextBox is defined as
<ControlTemplate x:Key="ComboBoxTextBox"
TargetType="{x:Type TextBox}">
<Border x:Name="PART_ContentHost"
Focusable="False"
Background="{TemplateBinding Background}" />
</ControlTemplate>
I don't see how overriding this template removes the dropdown list.
Ok I think I got really confused after reading all of your code and having a really looooooong day at work, I totally missed the point of your question.... which is
I want to add conditionnal formatting (just font color) to the textbox part of a combobox
Well if that's all you want to do, then it's really easy with just a simple style trigger.
I can achieve that with this xaml.
<ComboBox HorizontalAlignment="Center" VerticalAlignment="Center">
<ComboBox.Resources>
<Style TargetType="ComboBox">
<Style.Triggers>
<Trigger Property="Text" Value="MAL">
<Setter Property="Foreground" Value="DarkOrange" />
</Trigger>
</Style.Triggers>
</Style>
</ComboBox.Resources>
<ComboBoxItem>MAL</ComboBoxItem>
<ComboBoxItem>1</ComboBoxItem>
<ComboBoxItem>2</ComboBoxItem>
<ComboBoxItem>3</ComboBoxItem>
</ComboBox>
Hope this helps!
How to display text on an image, so it should always visible (because the image colors are mixed and unpredictable)?
I thought about two options:
Making the text border in white while the text itself will be black
Having the text displayed negatively to the picture
The 1st option would be preferred since it looks more solid.
Embedding the text is simple:
<Grid>
<Image Source="{Binding ImageLink}" Width="110" />
<TextBlock Text="{Binding Description}"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
</Grid>
Update on answer:
Sounds like a great idea except it doesn't work.
I tried your code, and here are the results:
The left image is when I set the Color property to White and ShadowDepth to 10.
I did this and it helps:
<Style x:Key="AnnotationStyle" TargetType="TextBlock">
<Setter Property="Background" Value="#70FFFFFF" />
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="HorizontalAlignment" Value="Center"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="TextAlignment" Value="Center"/>
<Setter Property="TextWrapping" Value="Wrap"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#CCFFFFFF" />
</Trigger>
</Style.Triggers>
</Style>
....
<TextBlock ... Style="{StaticResource AnnotationStyle}"/>
Here is what it looks like:
The best way to make the text more highlighted or contrasted is by using any effect, particularly the shader effects.
Microsoft is also make bitmap effect obsoleted since .NET 3.5 SP1, therefore your best bet is using any shader effect or create your own.
For example (from Karl Shifflett), you can use DropShadowEffect to "outline" your text but set the ShadowDepth to 0:
<Grid>
<Image Source="{Binding ImageLink}" Width="110" />
<TextBlock Text="{Binding Description}"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<TextBlock.Effect>
<DropShadowEffect ShadowDepth="0" Color="Blue" BlurRadius="10" />
</TextBlock.Effect>
</TextBlock>
</Grid>
For more sample, you can google WPF effects.
UPDATE: You can also turn off antialiasing on text by using attached property of TextOptions.TextRenderingMode and set it to "Aliased", or you can also use TextOptions.TextFormattingMode and set to "Display".
Try and compare this and see if it will fit your needs:
<StackPanel>
<TextBlock>
Hello World ... Ideal text formatting
</TextBlock>
<TextBlock TextOptions.TextFormattingMode="Display">
Hello World ... Display text formatting
</TextBlock>
</StackPanel>
Hope this helps.
Is there a way to "pre-render" a list in WPF without actually showing it to the user? I have a list that renders fairly slowly ( a few seconds ) the first time it is displayed to the user.
I'd like to pre-render/pre-draw the list so that the few seconds it takes to display the list to the users is not noticeable. I'd like this to happen while the app is starting up - while my splash screen is displayed.
What is the best way to accomplish this?
EDIT:
Here is my list item style. As you can see the target type is a Button. The button also has a RoutedEvent (Command) set on it.
<Style x:Key="Button_ProductFinder_Item" TargetType="Button">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid Width="690" Height="181" >
<Image Name="Up" Source="{StaticResource Img_ProductFinder_FriendUp}" Stretch="Uniform"/>
<Image Name="Down" Source="{StaticResource Img_ProductFinder_FriendDn}" Visibility="Hidden" Stretch="Uniform"/>
<Canvas Name="Clip" ClipToBounds="True" Height="162" Width="175" HorizontalAlignment="Left" Margin="0,10,0,0" >
<Image Name="DynamicFriend" Stretch="UniformToFill" Canvas.Left="16" Canvas.Top="-10" HorizontalAlignment="Left" Source="{Binding ImageSource}" Height="162" Width="162" />
<Canvas.RenderTransform>
<TransformGroup>
<TranslateTransform />
</TransformGroup>
</Canvas.RenderTransform>
</Canvas>
<TextBlock Name="DynamicName" Margin="210,69,0,0" Style="{StaticResource ButtonFriend_Textstyle}"
TextWrapping="Wrap" HorizontalAlignment="Left" Width="440" VerticalAlignment="Stretch" Height="Auto"
Text="{Binding ProductName}" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="Up" Property="Visibility" Value="Hidden"/>
<Setter TargetName="Down" Property="Visibility" Value="Visible"/>
<Setter TargetName="Clip" Property="RenderTransform">
<Setter.Value>
<TransformGroup>
<TranslateTransform Y="2"/>
</TransformGroup>
</Setter.Value>
</Setter>
<Setter TargetName="DynamicName" Property="RenderTransform">
<Setter.Value>
<TransformGroup>
<TranslateTransform Y="2"/>
</TransformGroup>
</Setter.Value>
</Setter>
<Setter TargetName="DynamicName" Property="Foreground" Value="#FFFFFF"/>
<Trigger.EnterActions>
<ctrls:ButtonSoundPlayerAction SoundFile="buttonclick.wav"/>
</Trigger.EnterActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Check WHAT is slow. Really. Itf it is like the db filling up the list, your question is totally off (as the perforamnce is not WPF realted).
How large is the list? I have a list of 5000 elements rendering in a moments notice. Mosty because my 4.0 virtual list only renders what is on the list. You are not data bound while fillng up the list, or?
Finally, what is slow in the rndering? Use a wpf profiler to find out and tell us - because at the nd of the day you may simply try to optimize the wrong thing.
You could always set the list (or the whole window the list is contained in) to collapsed in it's initial state, and then un-collapse it when you get word back from your data retrieval thread that it is done.
I have done that with a couple of my other programs and it works pretty well.
User executes the program, splash screen displays, and main window loads collapsed.
Data retrieval thread executes, gets data, reports it is finished.
Splash screen disappears, main window displays and list is populated.
Hello
First sorry for my english.
I have started recently my first project on wpf. I´m styling a custom DataGrid who have been defined programatically (the xaml code doesn´t exists).
I have styled all that i need in my datagrid control except a checkbox that i wrapped inside.
The problem is that in other place of my application i defined a checkbox style how are applying correctly but i can´t apply inside my datagrid.
Actually my datagrid doesn´t throw syntax errors but when the datagrid runs the checkbox styles doesn´t apply.
The style code look like this (its defined in a stylesheet)
... <Setter Property="DataGridCheckBoxColumn.ElementStyle">
<Setter.Value>
<Style TargetType="{x:Type CheckBox}">
<Setter Property="Background" Value="Yellow"/>
<Setter Property="BorderBrush" Value="{DynamicResource NormalBorderBrush}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type CheckBox}">
<BulletDecorator Background="Transparent">
<BulletDecorator.Bullet>
<Grid Width="13" Height="13">
<Border x:Name="Border" Background="Pink" BorderBrush="Black" BorderThickness="1,1,1,1" CornerRadius="2,2,2,2"/>
<Path x:Name="CheckMark" Stroke="Green" StrokeThickness="2" SnapsToDevicePixels="False" Data="M1.5000001,1.5833334 L9.7920001,9.6666667 M1.5420001,9.6666667 L9.7083333,1.5000001" Margin="1" ClipToBounds="False" StrokeEndLineCap="Round" StrokeStartLineCap="Round"/>
</Grid>
</BulletDecorator.Bullet>
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" RecognizesAccessKey="True"/>
</BulletDecorator>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Setter.Value>
</Setter>...
Its exactly the same that it`s applying in the apliccation.
I´ve read a lot about it but i can´t to apply it, i tried, also, setting the setter property to "DatagridBoundColum.ElementStyle" and also to "CellStyle" but it doesn´t work.
Any suggest??
Thank a lot.
Do it like you would do in xaml:
<UserControl.Resources>
<DataTemplate x:Key="CheckBoxTemplate">
<CheckBox Style="{StaticResource AnyResourceKeyInApplciation}"/>
</DataTemplate>
</UserControl.Resources>
<DataGrid x:Name="dataGrid" />
this.dataGrid.Columns.Add(new DataGridTemplateColumn
{
CellTemplate = this.Resources["CheckBoxTemplate"] as DataTemplate
}
);
Thanks for your Reply vorrtex.
I didn´t apply it exactly but it helped me to find the solution, however i would have liked not to modify the VB code and only to modify it the xaml style tag.
I find an object how simplify this task. The syntax it´s the following:
column2.ElementStyle = Application.Current.FindResource("CheckBoxStyle")
It´s applying style ok inside the datagrid. But actually it´s placing at left border of the cell. I´ll try to find why.
Thanks again.
You can try this
<Controls:DataGridCheckBoxColumn Header="Homme" Binding="{Binding Homme}">
<Controls:DataGridCheckBoxColumn.ElementStyle>
<Style TargetType="CheckBox" BasedOn="{StaticResource {x:Type CheckBox}}">
<Setter Property="Margin" Value="4,0,0,0"/>
</Style>
</Controls:DataGridCheckBoxColumn.ElementStyle>
</Controls:DataGridCheckBoxColumn>
I would like to know if there is any way to style a WPF layout grid's cells, rows and columns. I've been trying to find any information and the few mentions I've found have not been that informative.
I would like to style the grid to look like the one in the linked screenshot.
If the actual control does not support it, can I inherit it somehow and do it then? I am quite new to WPF so any help would be very appreciated.
One other thing, I know I can style each and every control within the grid, but it seems like overkill. I would like to have a grid that does it itself.
screenshot http://img21.imageshack.us/img21/2842/capturehz8.png
#Dan recommends WPF Unleashed, which I'm currently reading. Just this morning, I come across a section addressing your question.
Chapter 6, Page 161:
FAQ: How can I give Grid cells background colors, padding, and borders like I can with cells of a HTML Table?
There is no intrinsic mechanism to give Grid cells such properties, but you can simulate them pretty easily thanks to the fact that multiple elements can appear in any Grid cell. To give a cell a background color, you can simply plop in a Rectangle with the appropriate Fill, which stretches to fill the cell by default. To give a cell padding, you can use auto sizing and set the Margin on the appropriate child element. For borders, you can again use a Rectangle but give it an explicit Stroke of the appropriate color, or you can simply use a Border element instead.
Just be sure to add such Rectangles or Borders to the Grid before any of the other children (or explicitly mark them with the ZIndex attached property), so their Z order puts them behind the main content.
Btw, WPF Unleashed rocks. Its very well written, and the print in full color makes it even more easier to read.
Here's a quick (very rough sample) that you could hack around to get the format you want (if you're serious about working with WPF, you'll find Blend an enormous help in getting your layouts looking good):
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Page.Resources>
<Style x:Key="CustomerDefinition" TargetType="TextBlock">
<Setter Property="Control.FontFamily" Value="Tahoma"/>
<Setter Property="Control.FontSize" Value="12"/>
<Setter Property="Control.Foreground" Value="Red"/>
</Style>
<Style TargetType="{x:Type Label}">
<Setter Property="Width" Value="100"/>
</Style>
<Style x:Key="{x:Type TextBox}" TargetType="{x:Type TextBox}">
<Setter Property="SnapsToDevicePixels" Value="True"/>
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="KeyboardNavigation.TabNavigation" Value="None"/>
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="MinWidth" Value="120"/>
<Setter Property="MinHeight" Value="20"/>
<Setter Property="AllowDrop" Value="true"/>
<Setter Property="Width" Value="200"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBoxBase}">
<Border
Name="Border"
Background="#FFEBE9E9"
BorderBrush="#FF8B8787"
BorderThickness="1"
CornerRadius="2"
Padding="3">
<ScrollViewer x:Name="PART_ContentHost" Margin="0"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="Border" Property="Background"
Value="#EEEEEE"/>
<Setter TargetName="Border" Property="BorderBrush"
Value="#EEEEEE"/>
<Setter Property="Foreground" Value="#888888"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<LinearGradientBrush x:Key="NormalBrush" StartPoint="0,0" EndPoint="0,1">
<GradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Offset="0.0" Color="#FFF0EDED"/>
<GradientStop Offset="1.0" Color="#FFE1E0E0"/>
</GradientStopCollection>
</GradientBrush.GradientStops>
</LinearGradientBrush>
</Page.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="26"/>
<RowDefinition Height="23"/>
<RowDefinition Height="24"/>
<RowDefinition Height="24"/>
<RowDefinition Height="24"/>
</Grid.RowDefinitions>
<TextBlock
Grid.ColumnSpan="2"
Grid.Row="0"
Style="{StaticResource CustomerDefinition}"
Text="Customer Definition"/>
<Border
Grid.Column="0"
Grid.Row="1"
Background="#FFEBE9E9"
BorderBrush="#FF8B8787"
BorderThickness="1">
<StackPanel Background="{StaticResource NormalBrush}" Orientation="Horizontal">
<Label Content="Customer Code"/>
<TextBox Text="SMITHA 098 (normally I'd bind here)"/>
</StackPanel>
</Border>
<Border
Grid.Column="1"
Grid.Row="1"
Background="#FFEBE9E9"
BorderBrush="#FF8B8787"
BorderThickness="1">
<StackPanel Background="{StaticResource NormalBrush}" Orientation="Horizontal">
<Label Content="Customer Type"/>
<TextBox Text="PRIVATE INDIVIDUAL"/>
</StackPanel>
</Border>
</Grid> </Page>
The WPF Grid doesn't have visible cells as such. Think of them as invisible grid lines against which you can have child elements be aligned.
So, to style the grid's cells, you have to style the items that are aligned inside the grid.
It is confusing to think of the Grid as being anything like a WinForms DataGrid. I guess its closest WinForms equivalent is the TableLayout control.
Check out some 3rd party grid controls. I used the DevExpress one while it was in beta and found it pretty straightforward.
I would recommend using borders for your styling.
You could recreate that layout pretty easily by creating borders for each row and each column and set the rowspans and colspans accordingly.
You will have 5 borders with colspan 2, these borders will take care of your gradient backgrounds for each row and the borders along the top and bottom of each row. Then you will have 2 borders with rowspan 5 these will handle the column borders. Imagine that you are overlaying the borders to form the visual grid effect you are after.
For the header and outer border, just wrap the entire grid with a border and style as needed.
I would recommend storing your styles as resources so you can keep all your styling info in one place.
Take care to learn how the styling works because it is pretty powerful, but there is a learning curve as it is quite different to the way CSS works. I would recommend reading WPF Unleashed if you can.
I found this post when looking for method for setting margin (or padding) for DataGrid cells. My problem was solved thanks to example xaml code posted at (near the end) -- pretty minimalistic.
http://forums.silverlight.net/forums/p/16842/55997.aspx