This question already has answers here:
How to create a custom WPF XAML style for check box images
(2 answers)
Closed 1 year ago.
Can anyone know if there is a simple way to replace checkbox checkmark by image?
I have two images for "checked" and "unchecked" checkbox state. I don't know how to use them instead of checkmark.
I also tried to replace content with StackPanel and put Image and TextBlock inside. Images are switching by triggers. It works fine but I have no idea how to remove checkmark icon.
I googled a lot and found complicated solutions with tons of XAML (BulletDecorator etc). I personaly don't like to complicate my life and I believe there is a simplier solution.
You could simply define your own ControlTemplate for the Checkbox, in which you display your images instead of the default tick. You can find the default ControlTemplate for the Checkbox in the CheckBox Styles and Templates page on MSDN.
When defining your own ControlTemplate, it's often a good idea to start with the default. Get that working in your project and then you can start tweaking it to your liking. That way, it should keep all the default behaviours that users are used to from a Checkbox.
But this is WPF we're talking about here... with a little lateral thinking, it's easily possible to make several controls look like other controls. For example, here is a ToggleButton with a custom ControlTemplate that makes it look like a Checkbox, but with an Image that changes when you click on it instead of the normal tick mark:
<ToggleButton Content="I'm An Image CheckBox Label" Foreground="Black">
<ToggleButton.Template>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<StackPanel Orientation="Horizontal">
<Image>
<Image.Style>
<Style>
<Setter Property="Image.Source"
Value="/AppName;component/Images/Image1.jpg" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsChecked,
RelativeSource={RelativeSource AncestorType=
{x:Type ToggleButton}}}" Value="True">
<Setter Property="Image.Source"
Value="/AppName;component/Images/Image2.jpg" />
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
<ContentPresenter Content="{TemplateBinding Content}"
Margin="5,0,0,0" />
</StackPanel>
</ControlTemplate>
</ToggleButton.Template>
</ToggleButton>
It would also be easy to convert this to a CheckBox as that also uses the IsChecked property... you could probably even just replace all instances of the word ToggleButton with the word Checkbox and it should work.
Related
I want to put a tooltip to a button for enabling and disabling in WPF. I have mentioned the tried code below. But My tried code does not solve my problem. I have no idea should I use the separate property for this.
Code:
<dc:GeometryButton
Grid.Column="11"
Command="{Binding Path=GeneratePrintTemplateFilesCommand}"
Geometry="{StaticResource {x:Static dc:Geometries.Print}}"
ToolTip="{Binding Path=GeneratePrintTemplateFilesFeatureToolTip}"
Style="{StaticResource FormBuilderClient_TopToolbarGeometryButton_Style}"/>
I need your help to solve this. Thank you.
Same tool tip when disabled
If you want to show the same tool tip for both the enabled and disabled state of the button, you have to set the ShowOnDisabled property of the ToolTipService to True on your button.
ToolTipService.ShowOnDisabled="True"
Different tool tips through binding
If want to show different tool tips by changing the bound property GeneratePrintTemplateFilesFeatureToolTip in your view model on button click e.g. in your GeneratePrintTemplateFilesCommand, the first solution also works. However, you must implement INotifyPropertyChanged in this case, otherwise the button will not get notified of the changed tool tip text.
Different tool tips with style
An alternative for showing different tool tips for the enabled and disabled states of your button is to add a trigger to the Style of the button and make it depend on the IsEnabled property. You can merge this with your existing style. Note that I use two different properties to bind to, one for enabled and one for disabled. In practice, you would rather use static resources here, instead of properties on a view model, because they do not change here.
<Style x:Key="FormBuilderClient_TopToolbarGeometryButton_Style"
TargetType="{x:Type dc:GeometryButton}"
BasedOn="{StaticResource {x:Type dc:GeometryButton}}">
<Setter Property="ToolTip"
Value="{Binding GeneratePrintTemplateFilesFeatureToolTipEnabled}"/>
<Style.Triggers>
<Trigger Property="IsEnabled"
Value="False">
<Setter Property="ToolTip"
Value="{Binding GeneratePrintTemplateFilesFeatureToolTipDisabled}"/>
</Trigger>
</Style.Triggers>
</Style>
Make sure to remove the tool tip property from the button control itself and add the ShowOnDisabled property setting from above., otherwise your tooltip either will not change or not be displayed in disabled state.
<dc:GeometryButton Grid.Column="11"
Command="{Binding Path=GeneratePrintTemplateFilesCommand}"
Geometry="{StaticResource {x:Static dc:Geometries.Print}}"
ToolTipService.ShowOnDisabled="True"
Style="{StaticResource FormBuilderClient_TopToolbarGeometryButton_Style}"/>
I have looked for a solution to my problem on Google for hours, but there isnt much information to find.
I am using WPF Toolkit v2.2.1.
I have a Color Picker control in my WPF application, which needs to be custom styled. I am editing the control template of the Color Picker in App.xaml to apply to all color pickers.
As soon as I choose to use the template all available colors dissapear from the Color Picker. I have tried to assign new available colors from code with no success.
The Collection of colors are there, they are just not displayed it seems.
This is how the CP is defines in my mainwindow.xaml
<xctk:ColorPicker x:Name="cpRing" SelectedColorChanged="cpRing_Changed" HorizontalAlignment="Left" Margin="238,5,0,0" VerticalAlignment="Top" Height="20" Width="39" Foreground="Black"/>
The control template is too large to paste here unfortunately. But this should be easily reproduceable by adding a CP to a wpf window and rightclick it in designview and choose Edit Template. As soon as it is applied the colors will dissapear, without changing anything.
Does anybody know what to do to get the avaiable colors to display when editing the control template?
Best regards
yep, it has something wrong with it's style. But if you observe it's style carefully you will find out the problem:
search key word StandardColors or AvailableColors in xaml, here is StandardColors's template:
<ListBox x:Name="PART_StandardColors" Grid.Row="1">
<ListBox.Style>
<Style TargetType="{x:Type ListBox}">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="ItemsPanel">
....
</ListBox.Style>
</ListBox>
you can see the listbox has not set itemsource, so you can add it by yourself:
<ListBox x:Name="PART_StandardColors" ItemsSource="{TemplateBinding StandardColors}" Grid.Row="1">
edit listbox of AvailableColors :
<ListBox x:Name="PART_AvailableColors" ItemsSource="{TemplateBinding AvailableColors}" Grid.Row="1">
now it works.
I'm using some fancy WPF-based UI framework that defines ControlTemplates for all the basic controls. So if I have a ListBox, it is styled according to the theme of this framework.
I'd like to use a single ListBox that has a completely different style, and so I'd like to disable the ControlTemplate for this particular control only and build up a style from scratch.
I've tried setting the Template property to null on this control, as shown below, but it didn't work:
<Setter Property="Template" Value="{x:Null}" />
How can I reset the ControlTemplate for this control in order to get rid of the framework-specific styles and weave my own?
No need to resort to styles and setters if you only want to change the template for this one control:
<TextBox>
<TextBox.Template>
<ControlTemplate>
<Rectangle Width="200" Height="20" Fill="Red"/>
</ControlTemplate>
</TextBox.Template>
</TextBox>
I have a Tab Control that has a whole set of close able tab items, each tab item has View with a that has a scroll able section(each view is the same not same instance), the issue that I am having is that if you scroll on one tab its cascades to all the other tabs, I was wandering if someone can tell me how I can stop this from happening?
Thanks All :)
This is the default behavior if your TabControl specifies a ContentTemplate.TabControls use virtualization, so they will re-use the template when you switch tabs instead of creating a new one each time.
This means the same ScrollViewer is being used regardless of which tab you are on. You can prove this by adding a Loaded event to your ScrollViewer and you'll see it only gets called once.
One way around this is to use a DataTemplate that has x:Shared="False", so it won't share the template. I have not tested to see if there are any performance issues with this.
<DataTemplate x:Key="TestTemplate" x:Shared="False">
<local:UserControl1 />
</DataTemplate>
<Style x:Key="TabItemStyle" TargetType="{x:Type TabItem}">
<Setter Property="Header" Value="Test" />
<Setter Property="ContentTemplate" Value="{StaticResource TestTemplate}" />
</Style>
...
<TabControl ItemsSource="{Binding SomeCollection}"
ItemContainerStyle="{StaticResource TabItemStyle}" />
Note that this seems to be very fussy... for example I need to put my ScrollViewer in a UserControl or it won't work. I also need to set TabItem.ContentTemplate instead of TabControl.ContentTemplate.
I want to implement something exactly like "Changing the Default Text in the Search Box" for a WPF search TextBox. The box should show some greyed out "Search.." text when it's empty, and then it should function normally when text is typed in. The linked article shows how to do this in javascript. How would one start down this path in WPF? The best idea I've had so far is another text box on top of the main one that goes invisible whenever the search textbox gets focus or text.
This style will show text using a the background property and a visualbrush. Once control gets focus the text is removed.
<TextBox.Style>
<Style TargetType="TextBox">
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=Text}" Value="">
<Setter Property="Background">
<Setter.Value>
<VisualBrush Stretch="None">
<VisualBrush.Visual>
<TextBlock Text="Enter value" Foreground="Gray"/>
</VisualBrush.Visual>
</VisualBrush>
</Setter.Value>
</Setter>
</DataTrigger>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=Text}" Value="{x:Null}">
<Setter Property="Background">
<Setter.Value>
<VisualBrush Stretch="None">
<VisualBrush.Visual>
<TextBlock Text="Enter value" Foreground="Gray"/>
</VisualBrush.Visual>
</VisualBrush>
</Setter.Value>
</Setter>
</DataTrigger>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsFocused}" Value="True">
<Setter Property="Background">
<Setter.Value>
<VisualBrush Stretch="None">
</VisualBrush>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBox.Style>
Try the InfoTextBox sample from Kevin Moore's Bag-o-Tricks. You can download it from
http://work.j832.com/2008/01/real-update-to-bag-o-tricks.html
The best way I think for these types of things is to set the background using a visual brush.
The visual brush lets you paint a background using Visual Elements, combine it with a trigger based on text being empty and it's done.
Example for Empty List Box message is here, basically the same thing.
http://adammills.wordpress.com/2010/08/04/simple-empty-template-for-itemscontrols/
As always in WPF, there are many ways to achieve your goal.
Perhaps the cleanest way is to subclass TextBox and add a new property called HintText. The template for your control would display HintText (probably in italics and gray) as long as Text is empty (""). Otherwise, it would display the Text just like a regular TextBox.
An alternative that doesn't involve writing your own control is to re-template TextBox and use the Tag property to store the hint text.
Another alternative is to write a UserControl that combines a TextBox with, say, a TextBlock inside the same Grid. The TextBlock would contain the hint text and would only be displayed if the TextBox's Text is empty. This is probably the easiest to achieve, but is also the least flexible.
I think the WatermarkTextBox included in the WPF extended toolkit does exactly what you want.
http://wpftoolkit.codeplex.com/wikipage?title=WatermarkTextBox&referringTitle=Documentation
You could transform the textbox to have gray text whenever its empty and a variable that would tell you that is empty, so that when you clicked Search it would not go searching for "Search..."
Or you could use something similar to what you are saying, but instead of a textbox above you could have text below. If on top you have a textbox with transparent background and on the bottom you have a label that has "Search" when the top textbox is empty that should solve the problem.