I want to create a column chart using the WPF toolkit, but I want to hide the Y axis and display the dependant value for each column below the X value.
Is this possible?? If not, what other way could be used to get this result??
Thanks in advance.
Yes, you can hide the Y-axis. You should add the y-axis explicitly to the Axes property of the chart and set the Opacity property, like this:
<charting:Chart.Axes>
<charting:LinearAxis Orientation="Y" Opacity="0" />
</charting:Chart.Axes>
As to the second question, you should change the AxisLabelStyle property. I answered a similar question here, you can look at the code and change the ControlTemplate according to your needs.
The template will look something like this, don't forget change bindings:
<Style x:Key="twoLabelsStyle" TargetType="charting:AxisLabel">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="charting:AxisLabel">
<StackPanel>
<TextBlock Text="{Binding Month}" />
<TextBlock Text="{Binding Number}" />
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Anyway if it will not still work - add your source code to your question, it can help much better.
Related
I have a custom radio button based on togglebutton:
<Style TargetType="{x:Type local:ToolbarRadioButton}" BasedOn="{StaticResource {x:Type ToggleButton}}">
<Setter Property="Width" Value="60"/>
<Setter Property="Height" Value="60"/>
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<StackPanel Orientation="Vertical">
<iconPacks:PackIconModern Kind="{Binding TbIcon, RelativeSource={RelativeSource AncestorType=RadioButton}}"
Height="30" Width="35" HorizontalAlignment="Center"/>
<TextBlock Text="{Binding TbText, RelativeSource={RelativeSource AncestorType=RadioButton}}" FontSize="12"
HorizontalAlignment="Center"/>
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
I use this control to create four toggle/radio buttons. I've horizontal centered the items in datatemplate, but I end up with this:
Forecast and its icon seem to be centered, but the others are partially left-aligned. They all use the same control so shouldn't they all be centered?
EDITS FOR CLARITY:
It doesn't matter which order I put them in, Forecast is always the one that's aligned correctly.
There is no whitespace in the text nor is there whitespace in the images and all images are sized according to the control defined above. Here's the implementation portion in case it's useful, though they're all the exact same:
<StackPanel Orientation="Horizontal" Grid.Column="0" Grid.Row="0">
<customs:ToolbarRadioButton TbText="Day" TbIcon="CalendarDay" GroupName="calViewType" x:Name="dayOnOff"/>
<customs:ToolbarRadioButton TbText="Week" TbIcon="CalendarWeek" GroupName="calViewType" x:Name="weekOnOff"/>
<customs:ToolbarRadioButton TbText="Month" TbIcon="CalendarMonth" GroupName="calViewType" x:Name="monthOnOff" IsChecked="True"/>
<customs:ToolbarRadioButton TbText="Forecast" TbIcon="PeopleMultiple" GroupName="calViewType" x:Name="forecastOnOff"/>
</StackPanel>
For future readers: I figured out the answer by digging into the documentation on Button. There is a property on buttons called HorizontalContentAlignment (and vertical, of course) that apparently needs to be set to align the visual content. You can't set the HorizontalAlignment property of the item that is the content explicitly; apparently, the button wants to do that for you.
I've been reading this documentation and I was wondering if it's possible to position the selection check box of the container? Specifically, this thing here:
Ideally, I want it aligned on the right. So far I've tried to use
<ListView.ItemContainerStyle>
<Style TargetType="WHAT DO I WRITE HERE?">
<Setter Property="HorizontalAlignment" Value="Right"/>
</Style>
</ListView.ItemContainerStyle>
With various TargetTypes. Is it even possible to position that Selection-box?
To be honest you're looking in the wrong place. The ItemContainerStyle is adjust the margin padding and such properties of the container of the items of a listview.
What You need is a style for a ListViewItem. Lucky for us it's easily available from the ListViewItem styles and templates from the MSDN Documentation.
I won't paste the whole code here since, it's huge and it's cause deviated focus from the actual code that you need to tweak.
From the style from the above link, pick the second style of the two mentioned and refer to the below code:
<Border x:Name="MultiSelectSquare"
BorderBrush="{ThemeResource SystemControlForegroundBaseMediumHighBrush}"
BorderThickness="2"
Width="20"
Height="20"
Margin="12,0,0,0"
VerticalAlignment="Center"
HorizontalAlignment="Left"
Visibility="Collapsed" >
<Border.Clip>
<RectangleGeometry Rect="0,0,20,20">
<RectangleGeometry.Transform>
<TranslateTransform x:Name="MultiSelectClipTransform"/>
</RectangleGeometry.Transform>
</RectangleGeometry>
</Border.Clip>
<Border.RenderTransform>
<TranslateTransform x:Name="MultiSelectCheckBoxTransform"/>
</Border.RenderTransform>
<FontIcon x:Name="MultiSelectCheck"
FontFamily="{ThemeResource SymbolThemeFontFamily}"
Glyph=""
FontSize="16"
Foreground="{ThemeResource SystemControlForegroundBaseMediumHighBrush}"
Visibility="Collapsed"
Opacity="0"/>
</Border>
The above code handles the checkbox kinda tick mark with border for SelectionMode="Multiple".
All the changes you want to do must be done in this style and the above code section of the style.
Please Note: I would advise not to play around with Visibility and Opacity property as they are modified using VisualStates. Don't worry about them they'll change states at runtime.
So, I've got a custom WPF control called WatermarkTextbox which extends TextBox. The only thing I added to the code is a string dependency property to hold the watermark text. The rest of the magic is in the Xaml (below).
<Style TargetType="wpfControls:WatermarkTextbox" >
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type wpfControls:WatermarkTextbox}">
<Grid>
<TextBox x:Name="baseTextBox" />
<TextBlock Margin="5,0,0,0" x:Name="watermarkText" IsHitTestVisible="False" FontWeight="Light" FontStyle="Italic" Foreground="DarkGray" Visibility="Hidden" Background="Transparent"
Text="{Binding RelativeSource={RelativeSource AncestorType=wpfControls:WatermarkTextbox}, Path=Watermark}" />
</Grid>
<ControlTemplate.Triggers>
<Trigger SourceName="baseTextBox" Property="Text" Value="">
<Setter TargetName="watermarkText" Property="Visibility" Value="Visible"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
and when used in my application:
<wpfControls:WatermarkTextbox Watermark="Text that disappears."/>
This works, mostly. I can set the watermark text, and when I start entering some text, it goes away. When I change the font size, it changes both the watermark and the text I enter; when I change the font weight, it only changes the text entered (which is what I want it to do). I can change the size of the textbox. That's all gravy.
The problem is when I start trying to change things like the textbox's background or border properties, like so.
<wpfControls:WatermarkTextbox Watermark="Text that disappears." Background="Yellow"/>
Nothing happens. Same behavior with BorderBrush and BorderThickness. Now, the part where I know just enough to know that there's some important concept that I don't know. If I change the template for my WatermarkTextbox to the following, it will let me set the background in my application like I want.
<Style TargetType="wpfControls:WatermarkTextbox" >
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type wpfControls:WatermarkTextbox}">
<Grid>
<TextBox x:Name="baseTextBox"
Background="{TemplateBinding Background}"/>
<TextBlock Margin="5,0,0,0" x:Name="watermarkText" IsHitTestVisible="False" FontWeight="Light" FontStyle="Italic" Foreground="DarkGray"
Text="{Binding RelativeSource={RelativeSource AncestorType=wpfControls:WatermarkTextbox}, Path=Watermark}" Visibility="Hidden" Background="Transparent"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger SourceName="baseTextBox" Property="Text" Value="">
<Setter TargetName="watermarkText" Property="Visibility" Value="Visible"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I assume that if I did the same for BorderBrush and BorderThickness, they would work as well.
So, my question is, why? What is it about these properties that makes them behave differently from FontSize and FontWeight or Height and Width? Why do I have to explicitly set the Background to {TemplateBinding Background} but not FontSize? Also, what other properties do I need to set to the TemplateBinding in order to make them work properly?
Some of the properties are inherited from their parent automatically. explanation
This is why you don't have to set FontSize.
As for "what else", it all depends on what you want to be able to set directly on the user control.
Although this isn't bullet proof, but my general rule of thumb is "if it is a property in the Brush Tab of the property window or is purely for visual aesthetics, it probably is not inherited"
Another way to look at it - if the setting would give weird results in general, it also is probably no inherited. Example: if you set the Margin property on a Grid, imagine if every sub-element inherited the same margins.
So i typically add the template bindings for all the non-Layout, visual properties (Background, Foreground, BorderBrush, etc.). Or i just add templatebindings for any properties i want to set directly to my usercontrol. There is no need to add a template binding if you never intend to set the property (explicitly or by style).
The font properties are inherited attached properties; they're an explicit special case. Incidentally, TextElement.Foreground is one of those.
Height and Width aren't inherited, but you've got XAML there that'll size to its parent by default, and you haven't done anything to disable that behavior.
Anything else, you need to explicitly do the TemplateBinding thing -- or if they'll change at runtime, you'll need to do a relativesource binding:
{Binding PropertyName, RelativeSource={RelativeSource TemplatedParent}}
There isn't any "first principles" explanation for this; it's all just arbitrary implementation details.
Is it possible to create a style for ToolTip that would place an image next to the Item on which the tool tip resides and then show the tool tip text when the user hovers over the image? Something like this:
Currently I am doing a StackPanel to add the image with the tool tip like so:
<StackPanel Orientation="Horizontal">
<CheckBox Content="Reload Employee Data"
IsChecked="{Binding AdjustmentSettings.ReloadEmployeeData}"
Grid.Row="0"
Grid.Column="0">
</CheckBox>
<Image Source="/DelphiaLibrary;Component/Resources/info.ico"
ToolTip="Check if you want to re-upload ...."/>
</StackPanel>
EDIT
Just to clarify, I am looking for a way to style ToolTip such that if I define ToolTip on any object (i.e., Button, CheckBox, etc.) the info image is shown and the tool tip text is placed on this info image.
I would like to be able to do something like this and still get the same as the stack panel above:
<CheckBox Content="Reload Employee Data"
IsChecked="{Binding AdjustmentSettings.ReloadEmployeeData}"
Grid.Row="0"
Grid.Column="0"
ToolTip="Blah blah blah..."
Style="{StaticResource ToolTipImageStyle}">
</CheckBox>
And be able to apply this ToolTipImageStyle to any control (i.e., Button, CheckBox, TextBox, etc.). If that isn't possible can I style an individual control and just create different styles for different controls (one for buttons, another for TextBlock, etc.)?
This should do it. I couldn't figure out the color so just change that.
Source 1
Source 2
<Image Source="/DelphiaLibrary;Component/Resources/info.ico" Width="25" Height="25">
<Image.ToolTip>
<ToolTip Background="LightBlue">
<TextBlock Width="200" TextWrapping="WrapWithOverflow">
Check if you want to re-upload table foxpro.hrpersnl from the source. <LineBreak />
Leave unchecked to use existing data that has been previously uplaoded.
</TextBlock>
</ToolTip>
</Image.ToolTip>
</Image>
Update 1:
Source 1
In the App.xaml add this:
<Application.Resources>
<Style TargetType="{x:Type ToolTip}">
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToolTip}" >
<TextBox Background="LightBlue" Width="200" TextWrapping="WrapWithOverflow" Text="{TemplateBinding ToolTip.Content}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Application.Resources>
Then in your XAML file change to:
Note: This will work with all object's tool tips.
<Image Source="Images/MenuImageZoomOut.png" Width="25" Height="25"
ToolTip="Check if you want to re-upload table foxpro.hrpersnl from the source. Leave unchecked to use existing data that has been previously uplaoded." />
The image:
If this doesn't work, try this: Source
I am using the WPF Toolkit (System.Windows.Controls.DataVisualization.Toolkit) to generate a simple chart. In order to set my Y-axis to start from a value of zero, I set the Chart.Axes property like so:
<chartingToolkit:Chart Width="800" Height="400" Title="Usage" Style="{StaticResource ChartStyle}">
<chartingToolkit:Chart.Axes>
<chartingToolkit:LinearAxis Orientation="Y" Minimum="0" />
</chartingToolkit:Chart.Axes>
<chartingToolkit:LineSeries DependentValuePath="Value" IndependentValuePath="Key" ItemsSource="{Binding Data}" />
</chartingToolkit:Chart>
This works fine. However, when I try to set this property through a Style, intellisense does not even show Axes.
<Style x:Key="ChartStyle" TargetType="{x:Type chartingToolkit:Chart}">
<Setter Property="Axes">
<Setter.Value>
<chartingToolkit:LinearAxis Orientation="Y" Minimum="0" />
</Setter.Value>
</Setter>
</Style>
If I run the code, I get an ArgumentNullException saying Property cannot be null. This is Style.Setter.Property. I looked into the source code at Codeplex and found the Axes property:
[SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", Justification = "Setter is public to work around a limitation with the XAML editing tools.")]
[SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "value", Justification = "Setter is public to work around a limitation with the XAML editing tools.")]
public Collection<IAxis> Axes
{
get
{
return _axes;
}
set
{
throw new NotSupportedException(Properties.Resources.Chart_Axes_SetterNotSupported);
}
}
It says here that Setter is public but I cannot find any such public method. Now my questions are:
How is setting the property through a Style technically different from the first block of code in this question?
Is there a way I can set the Axes property through a Style?
Should I still be using the WPF Toolkit for charts? Is there a newer "canon" method to generate charts that I am not aware of?
you're close :)
You have to attach the style to the linearAxis itself, as there is not accessor from the chart style.
Style goes like this:
<Style x:Key="linearAxisStyle" TargetType="{x:Type charting:LinearAxis}">
<Setter Property="Orientation" Value="Y" />
<Setter Property="Minimum" Value="0" />
</Style>
Binding goes like this:
<chartingToolkit:Chart Width="800" Height="400" Title="Usage" Style="{StaticResource ChartStyle}">
<chartingToolkit:Chart.Axes>
<chartingToolkit:LinearAxis Style="{StaticResource linearAxisStyle}" />
<chartingToolkit:Chart.Axes/>
<chartingToolkit:LineSeries DependentValuePath="Value" IndependentValuePath="Key" ItemsSource="{Binding Data}" />
I'm answering in a new item since you changed the request....
You expect the default syntax to be something like this:
<Style x:Key="linearAxisStyle_Alt" TargetType="{x:Type charting:Chart}">
<Setter Property="Axes">
<Setter.Value>
<Setter Property="LinearAxis">
<Setter.Value>
<charting:LinearAxis Orientation="Y" Minimum="0" />
</Setter.Value>
</Setter>
</Setter.Value>
</Setter>
</Style>
The problem (which actually isnt one) is that the "Axes"-element doesn't have a style-property. Therefore you can not set a style inherited by its child - the LinearAxis.
That's why you receive the error: "property can not be null". Of course it cannot, cause its not existing.
So the final answer to your request is - (unfortunatly) its not possible.
Hopefully this gives you a better understanding.