How to do styling of data grid? - wpf

here i want to give alternate color white and grey to grid row . i hv done many try but i can not do styling of grid .the code is here
<Style TargetType="{x:Type wpftoolkit:DataGrid}">
<Setter Property="Margin" Value="0" />
<Setter Property="BorderBrush" Value="#A6A6A6" />
<Setter Property="BorderThickness" Value="0,1,0,0"/>
<Setter Property="Background" Value="{StaticResource GridBgBrush}" />
<Setter Property="RowBackground" Value="White" />
<Setter Property="AlternatingRowBackground" Value="#FFF3F6FA" />
<Setter Property="GridLinesVisibility" Value="Horizontal" />
<Setter Property="HorizontalGridLinesBrush" Value="Transparent" />
<Setter Property="RowHeaderWidth" Value="0" />
</Style>
here StaticResource GridBgBrush define earlier on this file as`
plz give proper solution .thanks in advance.

Make sure that your style is either defined within the resources section of your XAML file (after your GridBgBrush, so that it can reference it), or in a ResourceDictionary in your App somewhere making it accessible from anywhere. Without seeing more, I can't tell you where your problem is coming from. That is the correct way to define your style and I have several examples of this working as expected if you're interested in seeing them.
Another thing to note in case you didn't know, is that DataGrid (along with DatePicker) was introduced into WPF v4.0. This makes the WPF Toolkit (at least for the purposes of the DataGrid) unnecessary if you can target that version. After saying that, I suppose there's the slight chance that if you weren't aware you were using one and then styling the other, your style wouldn't work.
<XmlDataProvider x:Key="myData" Source="Data.xml" IsAsynchronous="True" />
<Style TargetType="{x:Type DataGrid}" x:Key="myStyle">
<Setter Property="AlternatingRowBackground" Value="Red"/>
</Style>
<Grid>
<DataGrid ItemsSource="{Binding Source={StaticResource myData}, XPath=persons/person}" AutoGenerateColumns="False" Style="{StaticResource myStyle}">
<DataGrid.Columns>
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding XPath=firstname}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding XPath=lastname}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>

You need to set AlternationCount property too.

Related

How to fix Xceed DateTimePicker ArgumentOutOfRangeException Error

I am using the Xceed DateTimePicker as the control in a wpf DataGrid for all columns that are bound to a Date property. Each of the those columns is defined as follows:
<DataGrid.Columns>
<DataGridTemplateColumn
Header="Charge Date"
Width="100">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock
Text="{Binding Path=ChargeDate, StringFormat=yyyy-MM-dd, Converter={StaticResource conDate}}"
HorizontalAlignment="Center" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<tk:DateTimePicker Value="{Binding Path=ChargeDate}" />
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
I don't think it is pertinent to my question, but for completeness sake, here is the styling for the pickers:
<Style TargetType="{x:Type tk:DateTimePicker}">
<Setter Property="TextAlignment" Value="Center" />
<Setter Property="Minimum" Value="2017-01-01" />
<Setter Property="DisplayDefaultValueOnEmptyText" Value="False" />
<Setter Property="ShowButtonSpinner" Value="False" />
<Setter Property="TimePickerVisibility" Value="Collapsed" />
<Setter Property="AutoCloseCalendar" Value="True" />
<Setter Property="Format" Value="Custom" />
<Setter Property="FormatString" Value="yyyy-MM-dd" />
</Style>
This works for datagrid cells that are already populated or when I am entering data in a new row. However when I click on an empty cell in an existing row, I get the following exception:
System.ArgumentOutOfRangeException: 'SelectedDate value is not valid.'
Why is the error only when I am enter data in an existing row? No code-behind is being executed when this exception happens so I don't know where to look for the problem.
I had the same issue. To fix this set the ClipValueToMinMax property to "True". This will prevent the value from going below minimum/above maximum without throwing an exception.
<xceed:DateTimePicker Value="{Binding DateTime}"
Minimum="{Binding DateTimeMinimum}"
Maximum="{Binding DateTimeMaximum}"
ClipValueToMinMax="True"/>
Since you have set the Minimum property to 2017-01-01, you should also set the default value to the same date:
<Style TargetType="{x:Type tk:DateTimePicker}">
<Setter Property="TextAlignment" Value="Center" />
<Setter Property="Default" Value="2017-01-01" />
<Setter Property="Minimum" Value="2017-01-01" />
<Setter Property="DisplayDefaultValueOnEmptyText" Value="False" />
<Setter Property="ShowButtonSpinner" Value="False" />
<Setter Property="TimePickerVisibility" Value="Collapsed" />
<Setter Property="AutoCloseCalendar" Value="True" />
<Setter Property="Format" Value="Custom" />
<Setter Property="FormatString" Value="yyyy-MM-dd" />
</Style>
You will get an ArgumentOutOfRangeException if the default value or value is less than the minimum value and this makes perfect sense.

WinRT horizontal menu autosize width of textblock so not truncated

I am trying (on WinRT Universal App) to have a top menu that doesn't have truncated text.
I get my items from my server and show them to my user, the problem is that I am showing items have 4 characters and some have 10 (or in-between). So some of them are truncated:
What i would like is to have a a textblock that can auto re-size it self, so that the word is not truncated, does anyone know how to do this?
here is my XAML code:
<GridView ItemsSource="{Binding Channels}"
SelectionMode="None"
IsRightTapEnabled="False"
IsSwipeEnabled="False"
IsItemClickEnabled="True"
Margin="5">
<GridView.ItemTemplate>
<DataTemplate>
<TextBlock Style="{StaticResource ChannelMenuHyperButtonStyle}"
Text="{Binding Name}"
Margin="10,0,10,0">
</TextBlock>
</DataTemplate>
</GridView.ItemTemplate>
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<WrapGrid Orientation="Vertical" />
</ItemsPanelTemplate>
</GridView.ItemsPanel>
</GridView>
Style code:
<Style x:Key="ChannelMenuHyperButtonStyle" TargetType="TextBlock">
<Setter Property="Foreground" Value="{StaticResource DmBlueBrush}" />
<Setter Property="FontWeight" Value="Normal" />
<Setter Property="FontSize" Value="18" />
<Setter Property="Padding" Value="5,5,5,5" />
</Style>
thanks you for your help!
As you only need one row of items I would suggest to use a VirtualizingStackPanel as the ItemsPanel (Instead of a WrapGrid). Don't forget to set it's orientation to horizontal.
A Stackpanel would also work but it might become heavy in memory if you have a very high amount of categories.
Why? Because GridViews and Listviews use a WrapGrid as the default ItemsPanel, all items in an WrapGrid will have the same size (the size of the first one will be applied to all of them). They have this limitation because they are virtualized panels that can automatically layout their items in multiple rows/colums.
I believe the Issue is that you have both margin and padding applied. For Titles that have more than 6 Char's the overlapping padding/margin is "truncating" your data.
Consider removing the Padding value from the horizontal lines in the Style "ChannelMenuHyperButtonStyle".
<Style x:Key="ChannelMenuHyperButtonStyle" TargetType="TextBlock">
<Setter Property="Foreground" Value="{StaticResource DmBlueBrush}" />
<Setter Property="FontWeight" Value="Normal" />
<Setter Property="FontSize" Value="18" />
<Setter Property="Padding" Value="0,5,0,5" />
</Style>
Remember Margin is making space from the outside of the bounds, padding is making space from inside the bounds.

Dynamically Display Grid Content

I have 3 different layouts (similar to I guess what you would call Skins but the layouts are hugely different, not just changes to colors and fonts) which I have developed for my application. The layouts are used for displaying the same data, but in a completely different format. Each of these layouts have been constructed within their own Grid.
I want my application to decide which layout to display dynamically based on a string value available at runtime.
What's the best way to get a parent Grid to display a Child Grid dynamically?
I'm trying to find some sort of magical DataTemplate / DataBinding / Templating method but just can't seem to find the best way. Alternatively, should I be looking at a different method of displaying these different layouts? Like an ItemsControl or similar?
Ben
I usually use a ContentControl and DataTrigger to determine what ContentTemplate to use.
For example,
<ContentControl Content="{Binding MyViewModel}">
<ContentControl.Resources>
<DataTemplate x:Key="DefaultTemplate">
<TextBlock Text="DefaultTemplate" />
</DataTemplate>
<DataTemplate x:Key="TemplateA">
<TextBlock Text="Template A" />
</DataTemplate>
<DataTemplate x:Key="TemplateB">
<TextBlock Text="Template B" />
</DataTemplate>
</ContentControl.Resources>
<ContentControl.Style>
<Style TargetType="{x:Type ContentControl}">
<Setter Property="ContentTemplate" Value="{StaticResource DefaultTemplate}" />
<Style.Triggers>
<DataTrigger Binding="{Binding SelectedView}" Value="ViewA">
<Setter Property="ContentTemplate" Value="{StaticResource TemplateA}" />
</DataTrigger>
<DataTrigger Binding="{Binding SelectedView}" Value="ViewB">
<Setter Property="ContentTemplate" Value="{StaticResource TemplateB}" />
</DataTrigger>
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>

ComboBox highlighting

I have a problem with my combobox I'm trying to customize. It is in a UserControl, and i want its BorderBrush property to change from Transparent to White when the mouse is over it (fade in/out would be bonus).
But I can't seem to get the proper Trigger syntax to do so... now I feel confused and I'm probably missing something obvious here.
Here is the combobox in question:
<ComboBox x:Name="comboEmiCategories" ItemsSource="{Binding}" Background="Transparent" Height="15px" Width="30px" BorderBrush="Transparent" Padding="-2">
<ComboBox.Resources>
<sys:Double x:Key="{x:Static SystemParameters.VerticalScrollBarWidthKey}">0</sys:Double>
</ComboBox.Resources>
<ComboBox.ItemTemplate>
<DataTemplate>
<Image Source="{Binding}" Stretch="UniformToFill" Height="15px" Width="30px" Margin="0" />
</DataTemplate>
</ComboBox.ItemTemplate>
<ComboBox.Template>
<ControlTemplate>
<ControlTemplate.Triggers>
<Trigger Property="ComboBox.IsMouseOver" Value="True">
<Setter Property="ComboBox.BorderBrush" Value="White" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</ComboBox.Template>
</ComboBox>
The trigger isn't working, even worse actually, if i don't comment out the whole ComboBox.Template part, the control disappears.
The main goal would be to have a ComboBox that stacks images and allows the user to select one out of a list, with nothing else than those images shown.
Thanks.
EDIT:
Mario's solution of putting it within a style works, but is it the only way to do this?
Try to place the below xaml within the Resources section of your window/usercontrol.
<Style x:Name="cbStyle" TargetType="ComboBox">
<Setter Property="BorderBrush" Value="Transparent" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="BorderBrush" Value="White" />
</Trigger>
</Style.Triggers>
</Style>
Of course you must refer this style in the ComboBox element. Also cut anything within the ControlTemplate, which is useless.
EDIT: your ComboBox section should look as follows:
<ComboBox x:Name="comboEmiCategories" ItemsSource="{Binding}" Height="15px" Width="30px" Style="{StaticResource cbStyle}" Padding="-2">
<ComboBox.Resources>
<sys:Double x:Key="{x:Static SystemParameters.VerticalScrollBarWidthKey}">0</sys:Double>
</ComboBox.Resources>
<ComboBox.ItemTemplate>
<DataTemplate>
<Image Source="{Binding}" Stretch="UniformToFill" Height="15px" Width="30px" Margin="0" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
Also put the Style declatarion in your UserControl.

Can I get this binding into a style?

I would like to take the xaml I currently have for a ComboBox (below), and condense it into something like the Style also shown below. I think this should work, but I have a 'Type'ing issue and not sure how to resolve it
"Cannot resolve the Style Property 'Margin'. Verify that the owning type is the Style's TargetType, or use Class.Property syntax to specify the Property.)
As I look at the existing ComboBoxStyle (also below) that I'm looking to base this new style off of, I see that I hadn't used x:Type, but it does seem to work.
Is there any reason this new style shouldn't work? What must I change?
Cheers,
Berryl
combo box, as is, working):
<ComboBox
x:Name="cboDepartmentFilter" Style="{StaticResource ComboBoxStyle}"
Margin="{StaticResource FliterPanelItem_Margin}" Width="{StaticResource FilterPanelItem_Width}"
ItemsSource="{Binding Path=DepartmentFilterControl.Choices}"
ToolTip="{Binding DepartmentFilterControlData.ToolTipTitle}"
/>
what I want:
<ComboBox Style="{StaticResource FilterPanelComboBoxStyle}" DataContext="{Binding DepartmentFilterControl}" />
<!- in some resource file ->
<Style x:Key="FilterPanelComboBoxStyle" BasedOn="{StaticResource ComboBoxStyle}">
<Setter Property="Margin" Value="{StaticResource FliterPanelItem_Margin}" />
<Setter Property="Width" Value="{StaticResource FilterPanelItem_Width}" />
<Setter Property="ItemsSource" Value="{Binding Choices}" />
<Setter Property="ToolTip" Value="{Binding ToolTipTitle}" />
</Style>
<!--
This style defines a common margin for items in a filter panel.
-->
150
existing ComboBoxStyle:
<!-- ComboBox Style -->
<Style x:Key="ComboBoxStyle" TargetType="ComboBox">
<Setter Property="Background" Value="{StaticResource headerBrush}" />
...
<Setter Property="Template">
<Setter.Value>
...
</Setter.Value>
</Setter>
<Setter Property="ItemContainerStyle" Value="{StaticResource ComboBoxItemStyle}" />
<Setter Property="IsSynchronizedWithCurrentItem" Value="True" />
</Style>
You still need to specify the TargetType in the derived style. (Or you prefix the properties with "ComboBox.")

Resources