How to center a WPF CheckBox within a ListBoxItem - wpf

I have a ListBox that uses an ItemContainerStyle. I have tried everything I can think of to get a CheckBox control to center vertically and horizontally. Any ideas?
<ListBox
IsSynchronizedWithCurrentItem="True"
Height="Auto" Width="Auto" DockPanel.Dock="Top"
ItemContainerStyle="{StaticResource lbcStyle}" />
<Style TargetType="ListBoxItem" x:Key="lbcStyle">
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="ContentTemplate" Value="{StaticResource editable}"/>
</Trigger>
</Style.Triggers>
<Setter Property="ContentTemplate" Value="{StaticResource nonEditable}"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/> '//i have tried stretch here also
<Setter Property="VerticalContentAlignment" Value="Stretch"/>
</Style>
CheckBoxes get this style:
<Style x:Key="editorCheckBox" TargetType="{x:Type CheckBox}">
<Setter Property="MinWidth" Value="67" />
<Setter Property="Height" Value="25" />
<Setter Property="Margin" Value="5,0,5,0" />
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="HorizontalAlignment" Value="Center" />
</Style>
Here are editable / non-editable:
<DataTemplate x:Key="editable">
<Border x:Name="brdEditable" Width="Auto" HorizontalAlignment="Stretch">
<DockPanel x:Name="dpdEditable" LastChildFill="True" Width="Auto" Height="Auto">
<Grid x:Name="grdEditable" Width="Auto" Height="Auto">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="25" />
<ColumnDefinition Width="25" />
<ColumnDefinition Width="100" />
<ColumnDefinition Width="100" />
<ColumnDefinition Width="80" />
<ColumnDefinition Width="110" />
<ColumnDefinition Width="110" />
<ColumnDefinition Width="60" />
<ColumnDefinition Width="90" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
'...
<CheckBox x:Name="chkActive" Grid.Column="7" Height="25" Style="{StaticResource editorCheckBox}" ToolTip="Is Construction Active?" IsEnabled="true" Validation.ErrorTemplate="{StaticResource validationTemplate}">
<CheckBox.IsChecked>
<Binding Path="Active">
<Binding.ValidationRules>
<DataErrorValidationRule></DataErrorValidationRule>
<ExceptionValidationRule></ExceptionValidationRule>
</Binding.ValidationRules>
</Binding>
</CheckBox.IsChecked>
</CheckBox>
'...
<ContentControl Name="ExpanderContent" Visibility="Collapsed" Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="14"></ContentControl>
</Grid>
</DockPanel>
</Border>
</DataTemplate>
<DataTemplate x:Key="nonEditable">
<Border x:Name="brdNonEditable" Width="Auto" HorizontalAlignment="Stretch">
<DockPanel Width="Auto" Height="25">
<Grid Width="Auto" Height="25">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="25" />
<ColumnDefinition Width="25" />
<ColumnDefinition Width="100" />
<ColumnDefinition Width="100" />
<ColumnDefinition Width="80" />
<ColumnDefinition Width="110" />
<ColumnDefinition Width="110" />
<ColumnDefinition Width="60" />
<ColumnDefinition Width="90" />
</Grid.ColumnDefinitions>
<CheckBox x:Name="chkActive" Grid.Column="7" Height="25" Style="{StaticResource editorCheckBox}" ToolTip="Is Construction Active?" IsEnabled="false" Validation.ErrorTemplate="{StaticResource validationTemplate}">
<CheckBox.IsChecked>
<Binding Path="Active">
<Binding.ValidationRules>
<DataErrorValidationRule></DataErrorValidationRule>
<ExceptionValidationRule></ExceptionValidationRule>
</Binding.ValidationRules>
</Binding>
</CheckBox.IsChecked>
</CheckBox>
<Label Content="calCompDate" Style="{StaticResource editorLabelList}" Grid.Column="8" ToolTip="{Binding Path= CompDate}" />
</Grid>
</DockPanel>
</Border>
</DataTemplate>
And thanks so much to everyone who has tried to help me solve this!

Try setting the ScrollViewer.HorizontalScrollBarVisibility property to "Disabled" on the ListBox. This forces the item containers to have a fixed width; otherwise, they can have any horizontal size, and horizontal alignment cannot be calculated sensibly.
Vertical alignment should be a matter of modifying the ListBoxItem style, as per Donnelle's answer.
Edit: In your code snippets, the CheckBox is inside a Grid which is inside a DockPanel which is inside a Border. Which element are you trying to center exactly? Are you sure the rest of them don't interfere? Here's how it looks for me with my suggestion and HorizontalContentAlignment="Center", and only the checkbox in the data template:
One more edit: I copy/pasted your grid/dockpanel/border exactly as they appear in the snippets you pasted, and the result is exactly the same - items centered horizontally.

I've had the same issue to. Have you tried setting "HorizontalAlignment" directly on the ListBoxItem in the style? (not HorizontalContentAlignment)

Have you tried setting HorizontalContentAlignment to "Stretch" on the ListBox itself? I believe this is necessary to make each ListBoxItem fill the width of the ListBox.

Setting the height on the ListBoxItem style-- rather than the checkbox-- does what I think you're after.

The checkbox is aligned top-left. For a quick and dirty, I have updated the margin on the checkbox to 4,3,0,0 on a row heigh of 20. May need to be adjusted depending upon your row height and if you want a buffer on the left. The margin attribute can get you out of odd format situations if you don't have time to write your own template or use other controls/containers.

Related

How to keep a button to the right of a datagrid header

I want to add a button to the datagrid header column and keep it at the right-most edge of the header column... no matter how wide it is. In my Xaml code I am using a DataTemplate where I attach the header column title and add a toggle button with a popup window.
<DataGrid>
<DataGrid.Resources>
<DataTemplate x:Key="HeaderTemplate">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<DataGrid.Resources>
<ContentControl Content="{Binding}" VerticalAlignment="Center"/>
<!--TODO: THIS IS THE BUTTON I WANT TO ANCHOR TO THE RIGHT-->
<ToggleButton Name="FilterButton" Grid.Column="1" Content="▼" Margin="2, 1, 1, 1" Padding="1, 0"/>
<Popup IsOpen="{Binding ElementName=FilterButton, Path=IsChecked}" PlacementTarget="{Binding ElementName=FilterButton}" StaysOpen="False">
<Border Background="White" Padding="3">
<TextBox Width="300"/>
</Border>
</Popup>
</Grid>
</DataTemplate>
</DataGrid.Resources>
When I launch my application I do see the header column with the toggle button right next to it. But I need it to be in the rightmost of any column header. Like this:
Can someone help me understand how to go about doing this with the code I currently have?
After a bit of fiddling, here's what I did to get it to work:
<DataGrid>
<DataGrid.Resources>
<Style TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
<DataTemplate x:Key="HeaderTemplate">
<Grid Margin="0, 0, -5, 0">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<ContentControl Content="{Binding}" VerticalAlignment="Center"/>
<!--TODO: THIS IS THE BUTTON I WANT TO ANCHOR TO THE RIGHT-->
<ToggleButton Name="FilterButton" Grid.Column="1" Content="▼" Margin="2, 1, 1, 1" Padding="1, 0"/>
<Popup IsOpen="{Binding ElementName=FilterButton, Path=IsChecked}" PlacementTarget="{Binding ElementName=FilterButton}" StaysOpen="False">
<Border Background="White" Padding="3">
<TextBox Width="300"/>
</Border>
</Popup>
</Grid>
</DataTemplate>
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridTextColumn HeaderTemplate="{StaticResource HeaderTemplate}" Header="Test"/>
</DataGrid.Columns>
</DataGrid>
There are two key changes.
First, I added this to DataGrid.Resources:
<Style TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
Which lets the HeaderTemplate fill the the entire header.
Second, I added a negative right margin to the Grid:
<Grid Margin="0, 0, -5, 0">
This compensates for the internal padding of the header's control template, moving the button fully to the right.
The problem here is that the content inside the header is Autosized. What you need to do is to change the Horizontal Alignment of the content. You can define a style for Column header and that will resolve the issue.
<DataGrid.Resources>
<Style TargetType="DataGridColumnHeader">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</DataGrid.Resources>

Adjusting WPF chart toolkit ColumnSeries (System.Windows.Controls.DataVisualization.Charting)

I am using the WPF chart toolkit (System.Windows.Controls.DataVisualization.Charting). All stylings are in the XAML and I only bound the data to chart from my ViewModel. Everything looks alright for the first time I click on a button to show the columnseries. When I click on the button for the second time, the chart becomes bigger/corrupted; It shows only part of the graph.
The graph is drawn for the first time:
And button clicked for the second time:
The code I am using is as below:
<dvc:Chart Cursor="Cross"
Background="#FFFFFCF2"
Title="{Binding Title}"
Height="410"
Width="750"
VerticalAlignment="Top"
Name="ChartContainer">
<dvc:Chart.Series>
<dvc:ColumnSeries ItemsSource="{Binding ChartData,UpdateSourceTrigger=PropertyChanged}"
IndependentValueBinding="{Binding Path= Key}"
DependentValueBinding="{Binding Path= Value}"
Name="SummariesChart"
Margin="0,0,0,0"
IsManipulationEnabled="False">
<dvc:ColumnSeries.DataPointStyle>
<Style TargetType="dvc:ColumnDataPoint">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="dvc:ColumnDataPoint">
<Grid>
<Rectangle Fill="{TemplateBinding Background}"
Stroke="Black" />
<Grid Margin="0,0, 0, 0"
HorizontalAlignment="Center"
VerticalAlignment="Top">
<TextBlock Text="{TemplateBinding FormattedDependentValue}"
Margin="2" />
</Grid>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</dvc:ColumnSeries.DataPointStyle>
</dvc:ColumnSeries >
</dvc:Chart.Series >
<dvc:Chart.Axes>
<dvc:LinearAxis Orientation="X"
Title="{Binding XTitle}"
Interval="1"
Location="Bottom"
ShowGridLines="True" />
<dvc:LinearAxis Orientation="Y"
Title="{Binding YTitle}"
ShowGridLines="True"
Location="Left" />
</dvc:Chart.Axes>
</dvc:Chart>
Also, to give you complete idea, I used a style on top of the page as follow:
<Style TargetType="dvc:Chart">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="dvc:Chart">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<dv:Title Content="{TemplateBinding Title}"
Style="{TemplateBinding TitleStyle}"
Margin="1" />
<Grid Grid.Row="1"
Margin="1,0,1,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<primitives:EdgePanel x:Name="ChartArea">
<Grid Canvas.ZIndex="-1"
Style="{TemplateBinding PlotAreaStyle}" />
<Border Canvas.ZIndex="10"
BorderBrush="#FF919191"
BorderThickness="1" />
</primitives:EdgePanel>
</Grid>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="BarDataPointStyle"
TargetType="{x:Type dvc:BarSeries}">
<Setter Property="Background"
Value="Blue"></Setter>
<Setter Property="Opacity"
Value="0" />
</Style>
When I remove <dvc:Chart.Axes> block, it works correctly consistently. But I need X-axe and Y-axes descriptions existing in this code block. Do you know how I can tackle this problem? I appreciate your help.
I found a way to resolve the issue. But still, I am skeptical that something is wrong with the styling or something.
I added Minimum = 0 and Maximum in LinearAxis tag. I bounded Maximum to a variable in my ViewModel. I got the length of the array and added one to the maximum variable(MaxNumberInXAxes).
<dvc:LinearAxis Orientation="X"
Title="{Binding XTitle}" I
nterval="{Binding XAxisInterval}"
Location="Bottom"
ShowGridLines="True"
AllowDrop="False"
Minimum="0"
Maximum="{Binding MaxNumberInXAxes}"/>
The graph becomes something like this:

XAML in WP8.1: Child Element Styles

I have a Grid and TextBlocks. I want to style all TextBlocks within the Grid. So I do this:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<Grid.Resources>
<Style TargetType="TextBlock">
<Setter Property="Margin" Value="0,0,0,15" />
</Style>
</Grid.Resources>
<StackPanel Grid.Column="0">
<TextBlock Text="myText" Style="{StaticResource TitleTextBlockStyle}" />
<TextBlock Text="myText" Style="{StaticResource TitleTextBlockStyle}" />
</StackPanel>
<StackPanel Grid.Column="1">
<TextBlock Text="123456" Style="{StaticResource TitleTextBlockStyle}" Foreground="{ThemeResource PhoneAccentBrush}" />
<TextBlock Text="123456" Style="{StaticResource TitleTextBlockStyle}" Foreground="{ThemeResource PhoneAccentBrush}" />
</StackPanel>
</Grid>
1) It's not working. TextBlocks don't get any Margins. Why?
2) How can I set the Style and Foreground properties of TextBlocks in the <Grid.Resources> tag?
1) It's not working. TextBlocks don't get any Margins. Why?
It's not working because you're assigning the style "TitleTextBlockStyle" to the TextBlocks. So the implicit style you defined in Grid.Resources doesn't come in to play. Remove the Style="{StaticResource TitleTextBlockStyle}" parts from the TextBlocks, and your margins will appear.
2) How can I set the Style and Foreground properties of TextBlocks in the <Grid.Resources> tag?
The same as you set everything else:
<Setter Property="Foreground" Value="AliceBlue"/>
or if you have a more elaborate brush:
<Setter Property="Foreground">
<Setter.Value>
<!-- Whatever brush you want -->
<Setter.Value/>
</Setter>
I assume that with "Set the style property of TextBlocks", you actually want your new style to inherit from an already defined style. In that case you can base your new style on an already existing style:
<Style TargetType="TextBlock"
BasedOn="{StaticResource StyleToInheritFrom}">
or, in your case, presumably:
<Style TargetType="TextBlock" BasedOn="{StaticResource TitleTextBlockStyle}">
<Setter Property="Margin" Value="0,0,0,15" />
</Style>
The full thing would look something like:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<Grid.Resources>
<Style TargetType="TextBlock" BasedOn="{StaticResource TitleTextBlockStyle}">
<Setter Property="Margin" Value="0,0,0,15" />
<Setter Property="Foreground" Value="{ThemeResource PhoneAccentBrush}"/>
</Style>
</Grid.Resources>
<StackPanel Grid.Column="0">
<TextBlock Text="myText" />
<TextBlock Text="myText" />
</StackPanel>
<StackPanel Grid.Column="1">
<TextBlock Text="123456" />
<TextBlock Text="123456" />
</StackPanel>
</Grid
What sort of margins are you looking for? If you are looking for left right margins, its due to your margin declaration. Declare like this:
<object Margin="left,top,right,bottom"/>
- or -
<object Margin="left,top"/>
- or -
<object Margin="thicknessReference"/>
Right now, you're just adding a bottom margin. You could also just add
Margin="15"
which will be interpreted as a thickness reference and set all values to 15

WPF: How to ignore defined style for concrete control

I have the Rectangle control style (for the type of Rectangle) defined in resource dictionary and it reflects the style for a Menu control also.
How to ignore these settings for Menu and leave it for (just) Rectangle? - Drawing purposes in canvas .... The Rectangle control is added to canvas dynamically from code behind. In main window is dockpanel, grid, menu, textblock and canvas controls. Style for rectangle also harm style properties for Menu (needed to keep the default style).
Thanks for advice
Main window controls:
<DockPanel HorizontalAlignment="Stretch" VerticalAlignment="Stretch" LastChildFill="True">
<Grid DockPanel.Dock="Top">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Menu Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="3" HorizontalAlignment="Stretch" Height="21" Name="menu" Style="{StaticResource ResourceKey=menuStyle}">
<MenuItem Header="File">
<MenuItem Header="Open image" Command="{Binding DoCommand}" CommandParameter="OpenImage"/>
<MenuItem Header="Exit" Command="{Binding DoCommand}" CommandParameter="Exit"/>
</MenuItem>
</Menu>
<RadioButton Margin="5" Grid.Row="1" Grid.Column="0" Content="Text selection" GroupName="ObjectType" IsChecked="{Binding Path=ObjectType, Mode=TwoWay, Converter={StaticResource ResourceKey=RadioButtonTypeConverter}, ConverterParameter=Text}" />
<RadioButton Margin="5" Grid.Row="1" Grid.Column="1" Content="Picture selection" GroupName="ObjectType" IsChecked="{Binding Path=ObjectType, Mode=TwoWay, Converter={StaticResource ResourceKey=RadioButtonTypeConverter}, ConverterParameter=Picture}" />
</Grid>
<pt:PropertyControl DockPanel.Dock="Right" SelectedObject="{Binding SelectedObject}" MinWidth="150"/>
<TextBlock DockPanel.Dock="Bottom" Height="100" Margin="5" Background="#FFF9F9F9">
</TextBlock>
<Canvas Name="canvas" MouseLeftButtonDown="Canvas_MouseLeftButtonDown" Background="White" Width="{Binding ElementName=ImgEdit, Path=Width}" Height="{Binding ElementName=ImgEdit, Path=Height}" MinWidth="300" MinHeight="100" VerticalAlignment="Top" MouseMove="canvas_MouseMove" MouseLeftButtonUp="canvas_MouseLeftButtonUp" >
<Image x:Name="ImgEdit" Source="{Binding BackgroundImage}" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Canvas>
</DockPanel>
Code of my Style resource dictionary:
<Style TargetType="{x:Type Rectangle}" >
<Setter Property="Fill" Value="Yellow" />
<Setter Property="Opacity" Value="0.2"/>
<Setter Property="StrokeThickness" Value="2"/>
<Setter Property="Stroke" Value="Red" />
</Style>

Show "pop up window" when is mouser over listBox item

I bind observable collection on listBox. I have data tempate on listbox item. It consit one image control and som textBlock.
If is mouse over on some listBox item I would like achieve this behavior:
Show PopUp/ToolTip (some "rectangle" with controls) and bind values from listBox current item.
And on textBox in item data template I have style, I would like change color of text in textBlock, for example from black to green.
Style is here:
<Style x:Key="FriedNickStyle" TargetType="TextBlock">
<Setter Property="Margin" Value="2,2,2,2"/>
<Setter Property="FontSize" Value="13"/>
<Setter Property="FontWeight" Value="Medium"/>
<Setter Property="Foreground" Value="Black"/>
</Style>
Sory for my english, I have problem how describe this behavior correct. I try many thing but any of them doesn’t work good.
Here is it my style:
<DataTemplate x:Key="FriendListBoxItemTemplate">
<Grid Name="RootLayout">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.3*"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="60"></RowDefinition>
</Grid.RowDefinitions>
<Image Margin="4,4,4,2" Grid.Column="0">
<Image.Source >
<MultiBinding Converter="{StaticResource avatarConverter}">
<Binding Path="ProfilePhoto"></Binding>
<Binding Path="StatusInfo.IsLogged"></Binding>
</MultiBinding>
</Image.Source>
</Image>
<Grid Grid.Column="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<TextBlock
Text="{Binding Path=Nick}"
Style="{StaticResource FriedNickStyle}"
Grid.Column="0" Grid.Row="0">
</TextBlock>
</Grid>
</Grid>
<DataTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<!--SHOW SOME POP UP WINDOW and bind properties from ITEM (VALUE)-->
<!--Change color of textBlock-->
</Trigger>
</DataTemplate.Triggers>
</DataTemplate>
Thank everybody who help me.
Well, I found this turorial, this article, by the MSDN and another stack overflow's question.
Basically, here's how:
<Popup Margin="10,10,0,13"
Name="Popup1"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Width="194"
Height="200"
IsOpen="True"> // change this to open it
<TextBlock Name="McTextBlock" Background="LightBlue" >
This is popup text
</TextBlock>

Resources