How can I create tabitems that look like hyperlinks and user is unaware that tabcontrol is used, i.e. no borders on tabitems? So it would like like horizontal menu bar (with no subitems).
You can overwrite the default TabControl.Template to hide the borders, then just style your TabItem headers to look like hyperlinks.
Here's an example of overwriting the TabControl.Template
<ControlTemplate x:Key="TabControl_NoHeadersTemplate" TargetType="{x:Type TabControl}">
<DockPanel>
<!-- TabItem Headers -->
<StackPanel IsItemsHost="True" DockPanel.Dock="Left" />
<!-- Selected Tab Content -->
<ContentPresenter ContentSource="SelectedContent" />
</DockPanel>
</ControlTemplate>
Then you can use just the following to apply the template:
<TabControl Template="{StaticResource TabControl_NoHeadersTemplate}" />
Related
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.
I have a simple override of the Control Template for a button in WPF that looks like this.
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<Rectangle x:Name="ButtonRectangle" Fill="{StaticResource BlueBrush}"/>
<ContentPresenter Panel.ZIndex="1"
HorizontalAlignment="Center"
VerticalAlignment="Center"/>
</Grid>
</ControlTemplate>
Typically the button will contain text "OK", "Cancel", etc. If the button is ever disabled I want the text Foreground property to update to a disabled text style. I haven't found any way to let the content in the content presenter know that it is disabled. Where am I going wrong with this one?
How can I know the default template element of a usercontrol when I trying to override it?
For example somebody have overrided the TabControl's template like this.
<TabControl>
<TabControl.Template>
<ControlTemplate TargetType="TabControl">
<StackPanel>
<ScrollViewer HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Disabled">
<TabPanel x:Name="HeaderPanel"
Panel.ZIndex ="1"
KeyboardNavigation.TabIndex="1"
Grid.Column="0"
Grid.Row="0"
Margin="2,2,2,0"
IsItemsHost="true"/>
</ScrollViewer>
<ContentPresenter x:Name="PART_SelectedContentHost"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
Margin="{TemplateBinding Padding}"
ContentSource="SelectedContent"/>
</StackPanel>
</ControlTemplate>
</TabControl.Template>
<TabItem Header="TabItem1">TabItem1 Content</TabItem>
<TabItem Header="TabItem2">TabItem2 Content</TabItem>
</TabControl>
How does he know there is <StackPanel> and <ContentPresenter> in the TabControl's template?
The TabControl class has a [TemplatePart] attribute that indicates mandatory parts of the template:
[StyleTypedPropertyAttribute(Property = "ItemContainerStyle", StyleTargetType = typeof(TabItem))]
[TemplatePartAttribute(Name = "PART_SelectedContentHost", Type = typeof(ContentPresenter))]
public class TabControl : Selector
In this case the template must contain a ContentPresenter named PART_SelectedContentHost. Everything else is optional, you can put anything you like in the template (as long as it makes sense of course).
When you are overriding a ControlTemplate for any control, you are defining how it will look. The <StackPanel> is just the layout control you are using, it could be a grid or any other layout control.
However the is something it needs to be there. If you look at the WPF control hierarchy, you can see several types of controls at the base levels, after Control, FrameworkElement, etc:
<ContentControl>
<HeaderedContentControl>
<ItemsControl>
<HeaderedItemsControl>
Each one of these have specific rendering options and parts. In your case a <TabControl> is an <Selector> which is a special type of an <ItemsControl>. This Selector has a Content and a TabPanel, thus the <TabPanel> and the <ContentPresenter> (which tells WPF where to render the Content).
The best way to aquire this knowledge is by looking at the default WPF templates for each control, for example the TabControl default template for WPF4 is here
See MSDN for default templates and styles.
I have some userControl that contain simple button.
I want to bind the button Content to the userControl Content - How to do it?
Set a name for the user control (for example x:Name="self") and in the Button
<Button Content={Binding ElementName=self}" />
Do you mean this or something else?
If the Button is inside the UserControl it is part of the UserControl's Content and can't recursively contain itself. The whole purpose of a UserControl is that you're explicitly defining a fixed set of Content. If you want variable Content then you should use a templated ContentControl something like this:
<ContentControl Content="{Binding SomeVariableValue}">
<ContentControl.Template>
<ControlTemplate TargetType="{x:Type ContentControl}">
<Border>
<!-- Other content from your user control -->
<Button Content="{TemplateBinding Content}"/>
</Border>
</ControlTemplate>
</ContentControl.Template>
</ContentControl>
I want to change the style of a combo box control to look like a hyperlink.
When user clicks on the hyperlink ( combo box) it show options in the combobox to select.
The idea is that I want combo box control to display as a plain text ( more readable form).
If anybody created this type of sytle please let me know.
You could edit the ComboBox template and replace the ContentPresenter with a Hyperlink-style button. This should work pretty well, and it is just a bit of XAML coding. You can find the original ComboBox template here, or using Expression Blend.
EDIT:
OK, well, you have a ComboBox template which looks something like this (extremely simplified!):
<ControlTemplate TargetType="{x:Type ComboBox}">
<Grid>
<!-- The popup that is displayed after you clicked on the ComboBox. -->
<Popup IsOpen="{TemplateBinding IsDropDownOpen}"
Placement="Bottom"/>
<!-- The button that is used to open the drop down. -->
<ToggleButton x:Name="btnOpenDropDown"
IsChecked="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"/>
<!-- The control which displays the currently selected item. -->
<ContentPresenter x:Name="contentPres"
Content="{TemplateBinding SelectionBoxItem}"/>
</Grid>
</ControlTemplate>
Actually, it is a bit more complicated because the ToggleButton must occupy the whole width (since the drop down should open whereever you click on the ComboBox), but it should display only on the right of the content. However, for your scenario, we can neglect this since you will not have a drop down button.
Now, since you only want to display the content as a hyperlink and no button besides it, you no longer need a distinction between ContentPresenter and ToggleButton. Therefore, instead of using a separate ContentPresenter, you could use the ToggleButton to present the content since it also has a Content property. Something like that:
<ControlTemplate TargetType="{x:Type ComboBox}">
<Grid>
<!-- The popup that is displayed after you clicked on the ComboBox. -->
<Popup IsOpen="{TemplateBinding IsDropDownOpen}"
Placement="Bottom"/>
<!-- The button that is used to open the drop down AND to display the content (now). -->
<ToggleButton x:Name="btnOpenDropDown"
Content="{TemplateBinding SelectionBoxItem}"
IsChecked="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"/>
</Grid>
</ControlTemplate>
Of course, there are some additional properties to move from the ContentPresenter to the ToggleButton.
Now, all you have to do is define another template for the ToggleButton which looks like a Hyperlink (and then assign this template to the ToggleButton above). Actually, this should not be difficult assuming that your content is always a string (again, simplified!):
<Style x:Key="hyperlinkButtonStyle" TargetType="{x:Type ButtonBase}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<TextBlock Text="{TemplateBinding Content}"
TextDecorations="Underline"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
This simplified code shows how you could do it. There are certainly other ways, and it still involves some work for you as the example was simplified. However, I cannot offer you the complete code.