Adding runtime label as content in checkbox wpf - wpf

I am dynamically creating the checkboxes at runtime and also applying the style at runtime. Designer has developed a checkbox like control that am applying at runtime. and he put a Label on that checkbox control to show the Text on the checkbox control as its content from the Database. But when i applying content of checkbox or label at runtime, it displays at the back of that checkbox control that is developed by the designer. How to make use of the Label control to show the content from the database on the checkbox control.
Kindly Suggest?
Thanks

It sounds to me like your designer forgot to include a <ContentPresenter/> in his checkbox template. If there is no ContentPresenter, the text you add as a comment will never be shown.
Here is an example of a custom CheckBox ControlTemplate that includes the required ContentPresenter:
<ControlTemplate TargetType="{x:Type CheckBox}">
<DockPanel>
<Border BorderThickness="1" BorderBrush="Black">
<Path x:Name="check" Width="10" Height="10"
Data=".... data for checkmark in checkbox ..." />
</Border>
<ContentPresenter/>
</DockPanel>
<ControlTemplate.Triggers>
<Trigger ... trigger for changing checkmark ... />
</ControlTemplate.Triggers>
</ControlTemplate>

You should to review your checkbox style. It is supposed to be that label(textbox) in style liyng under checkbox mark. Here is nearly right code for the chekcbox template:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Border Grid.Column="0">
<!--Place your mark here-->
</Border>
<Border Grid.Column="1">
<!--Place your label here-->
</Border>
</Grid>

Related

Strange border still resding on button; even after modifying the control template

I have a 'feedback' button which has this strange border:
So I searched online for some solutions and modified the control template, and I got this:
Control Template code:
<Button.Template>
<ControlTemplate TargetType="Button">
<ContentPresenter Content="{TemplateBinding Content}" />
</ControlTemplate>
</Button.Template>
So even after modifying the control template - I am getting a strange brown border. Help would be appreciated regarding this.
Button code:
<Button Grid.Row="3"
Grid.Column="2"
Grid.RowSpan="2"
Style="{StaticResource IconStyleBase}"
Name="Feedback_Button">
<Button.Template>
<ControlTemplate TargetType="Button">
<ContentPresenter Content="{TemplateBinding Content}" />
</ControlTemplate>
</Button.Template>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="218*" />
<RowDefinition Height="68*" />
</Grid.RowDefinitions>
<!--Icon-->
<Button Background="#3767B0"
Style="{StaticResource IconStyleContent}">
<!--Content-->
<Button.ContentTemplate>
<DataTemplate>
<Viewbox>
<TextBlock Padding="55"></TextBlock>
</Viewbox>
</DataTemplate>
</Button.ContentTemplate>
</Button>
<!--Icon Text-->
<Button Background="#FF2D5BA0"
Style="{StaticResource IconStyleSubBase}">
<!--Content-->
<Button.ContentTemplate>
<DataTemplate>
<Viewbox>
<TextBlock Padding="15">Feedback</TextBlock>
</Viewbox>
</DataTemplate>
</Button.ContentTemplate>
</Button>
</Grid>
</Button>
A DataTemplate defines the appearance of the the items that you set as Content of a button, but the button itself as a container has a default style and control template that defines how it looks like, along with its different states like mouse-over or pressed. That is where the border comes from.
You can try to create a style that sets the BorderThickness to 0 and apply it on each of your buttons. This approach works for control templates that bind the border thickness from their templated parent.
<Style x:Key="BorderlessButtonStyle" TargetType="{x:Type Button}" BasedOn="{StaticResource {x:Type Button}}">
<Setter Property="BorderThickness" Value="0"/>
</Style>
If this does not work or you want adapt the appearance of your buttons in detail, you have to extract and adapt the button style and control template.
Your custom control template does not work, because you did not apply it to the inner buttons and you should remove Content="{TemplateBinding Content}". Nevertheless, your button control template does not define any control states, so it will not be responsive at all.
You should copy the control template for Button from here, or extract it manually via Blend or Visual Studio. Then you can remove or the Border within it, change its thickness or color, so it will disappear. Moreover, you can adapt its various states to fit your desired style.
A notice on your design. It do not think that it is a good idea to nest buttons. Your control should either be a single button or a panel with two buttons in it, but that also only makes sense if they execute different actions in a related context, like split buttons do.

Not all content is clickable on custom control derived from button

iv'e got a "Cube" (Dice) control which derives from Button
Cube :
public class Cube : Button
{
public Cube()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(Cube), new FrameworkPropertyMetadata(typeof(Cube)));
}
...... // Stuff
}
Template (In general):
<ControlTemplate TargetType="{x:Type local:Cube}" x:Key="CubeControlTemplate">
<Border>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="40"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Border>
<Grid>
.......
</Grid>
</Border>
<Border Grid.Column="2">
<Grid>
.......
</Grid>
</Border>
<Grid>
</Border>
</ControlTemplate>
what it looks like :
the yellow marking shows that it is clickable only behind the Content , only if you really target your click where the Button is "Hidden" ..
any ideas why this happens ?
Without a Background mouse events will not be catched. Give your outer Border a transparent Color:
<ControlTemplate TargetType="{x:Type local:Cube}" x:Key="CubeControlTemplate">
<Border Background="Transparent">
.......
</Border>
</ControlTemplate>
Please check that you are not trying to click on an element that has a Null background. Hit testing requires a Brush to be set.
If your Border or your Grid has a Null background try setting it to Transparent.
If you are still having issues try debugging with Snoop.
http://snoopwpf.codeplex.com/

Having Trouble Styling and Editing AvalonDock Document Tab Panel

I'm trying to figure out how to make the VS2010 style for AvalonDock to function a little more like VS2010. The problem that I'm running into is that when there are more tabs than can fit in the header area there is no indication to the user that there are more tabs.
I thought that the tab headers were just clipped and not visible. I have a custom copy of the VS2010 style and went to the DocumentPane style:
<!--DocumentPane-->
<Style x:Key="{x:Type ad:DocumentPane}" TargetType="{x:Type ad:DocumentPane}"> ...
And found the tab headers (I think) as a "ad:DocumentTabPanel". I wrapped this in a ScrollViewer:
<ScrollViewer Style="{StaticResource ResourceKey=TabHeaderScrollViewer}" CanContentScroll="True">
<ad:DocumentTabPanel
x:Name="paneTabsPanel"
Panel.ZIndex ="1"
IsItemsHost="True"
TabItemStyle="{StaticResource CustomDocumentTabItemStyle}"/>
</ScrollViewer>
The scroll viewer is setup to have a custom style on it:
<Style x:Key="TabHeaderScrollViewer" TargetType="ScrollViewer">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ScrollViewer">
<Grid Background="{TemplateBinding Background}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<RepeatButton Command="ScrollBar.PageLeftCommand"></RepeatButton>
<ScrollContentPresenter Grid.Column="1"
x:Name="ScrollContentPresenter"
Cursor="{TemplateBinding Cursor}"
Margin="{TemplateBinding Padding}"
ContentTemplate="{TemplateBinding ContentTemplate}"/>
<RepeatButton Grid.Column="2" Command="ScrollBar.PageRightCommand"></RepeatButton>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
The problem I am having is that even when I load up a ton of tabs the scrolling doesn't work. I don't think this is an issue with my styling. It appears that the tab headers aren't in the VisualTree or have a collapsed visibility. I've been going through the AvalonDock source for a while, but I can't see how the headers are hidden.
I've already had to subclass some of the AvalonDock classes because I needed additional properties on them.
Can someone either explain/help me come up with a solution to scroll the tabs?
Problem was solved very simply. I had to set the HorizontalScrollBarVisibility="Auto". I checked http://msdn.microsoft.com/en-us/library/system.windows.controls.scrollviewer.horizontalscrollbarvisibility.aspx to see what the default value is for this property, but didn't see one there or on the ScrollViewer page. I assume it defaults to "Hidden".
Anyhow, once set to "Auto" the repeat buttons are shown only when the tabs overflow.

Bind page title to a text block in a style

OK, I have defined a style for Navigation Window. I have successfully styled Navigation buttons and even added page breadcrumbs to the Navigation menu. What I want is to add Page title next to the breadcrumbs:
Style x:Key="{x:Type NavigationWindow}" TargetType="NavigationWindow">
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="NavigationWindow">
<DockPanel Background="{StaticResource WindowBackgroundBrush}">
...
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="16"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
....
<StackPanel Grid.Column="4" Orientation="Horizontal">
<TextBlock Foreground="Gray"
VerticalAlignment="Center"
Text="{Binding Path=Title,
RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type Page}}}" />
</StackPanel>
</Grid>
</DockPanel>
...
</ControlTemplate>
</Setter.Value>
</Setter>
The binding doesn't work for the last TextBlock. (However it works just fine if not used within a style, but in regular XAML page code-behind) I have no idea why. Help? How to make it display the current page title? Thanks.
The problem is that within the ControlTemplate, there is no ancestor of type Page. The control you apply the template to may have an ancestor of type Page, but the ControlTemplate itself doesn't know about that. It only knows about ancestors in its own logical tree.
To help mitigate this issue, the WPF designers added the TemplateBinding markup extension, which allows you to apply the value of a property on the templated control to a property in the control template.
So, on the NavigationWindow, you should create a property that exposes the Title of the Page. Then you can use the following mark-up to bind to it:
Text="{TemplateBinding TitleProperty}"

Can I have two ContentPresenter pointing to in single Content or ContentSource in the ContentTemplate?

I have created a NavigationPane just like Outlook 2007. In Outlook, when the Pane is collapsed and the side bar is clicked, it used to popup the Selected NavigationItem content. I mimicked the same behavior using contentpresenter in the ControlTemplete (one for the TabControl's SelectItemHost and another for the Popup). But the problem is when the Popup is open up, the NavigationPane selected content when away and it appears when we switch back to the same navigation item from another navigation item. I am using TabControl and TabItem as NavigationPane and NavigationPaneItem.
I am pointing the "SelectedContent" as the ContentSource for the two ContentPresenter
You can define two ContentPresenter objects within a control template and point them both at the same content source if you like:
<ControlTemplate x:Key="WeirdButton" TargetType="Button">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Border Grid.RowSpan="2" Background="{TemplateBinding Background}" />
<ContentPresenter ContentSource="Content"/>
<ContentPresenter ContentSource="Content" Grid.Row="1"/>
</Grid>
</ControlTemplate>
This has some rather unusual side effects, however. Because you can't put the same visual into two places in the visual tree, this template will only work as expected if the child content of the button is NOT a visual (or derived from Visual). If the content is some other type of data and the visuals are generated by a data template everything works as expected. Setting the content of the button to a string (<Button Content="OK"/>) works also.
Note that this same effect could be achieved with a visual brush:
<ControlTemplate x:Key="WeirdButton" TargetType="Button">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Border Grid.RowSpan="2" Background="{TemplateBinding Background}" />
<ContentPresenter x:Name="presenter" ContentSource="Content"/>
<Rectangle Grid.Row="1"
Width="{Binding ActualWidth, ElementName=presenter}" Height="{Binding ActualHeight, ElementName=presenter}">
<Rectangle.Fill>
<VisualBrush Visual="{Binding ElementName=presenter}" Stretch="None" AlignmentX="Left"/>
</Rectangle.Fill>
</Rectangle>
</Grid>
</ControlTemplate>
The drawback of this approach is that you can't interact with controls in the visual brush. So if you want the buttons, textboxes, and other controls on the duplicate to also be interactive, you will have to follow an approach closer to the first template.

Resources