I saw the following code in stackoverflow:
<UserControl x:Class="WpfApplication3.UserControl1"
x:Name="Uc1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<UserControl.Resources>
<Style TargetType="Label">
<Setter Property="Foreground"
Value="{Binding Foreground, ElementName=Uc1, Mode=OneWay}"/>
</Style>
</UserControl.Resources>
<Grid>
<Label Content="Label 1"/>
<Label Content="Label 2"/>
</Grid>
</UserControl>
Question: I now wonder if I can target a specific label inside my usercontrol.resources for styling. Is it possible inside my userControl? If so then how?
A Style without a Key will be applied to all instances of the Target Type within the scope.
Give the style a Key, like,
<Style TargetType="Label" x:Key="MyLabel">
and then use the Key as following
<Label Content="Label 1" Style="{StaticResource MyLabel}" />
<!--Will not apply the style to Label 2-->
<Label Content="Label 2"/>
Edit:
I read your question again, seems you want to reference a Target from a Style, not reference a Style from a Target. Is that right? It sounds unnatural, it is like wanting to know the name of an instance of a derived class, from the base class.
Related
Given I have a control from somewhere called SomeControl
In MyUserControl.xaml I use SomeControl like so:
<Grid.Resources>
<Window.Resources>
<Style TargetType="local:SomeControl">
<Setter Property="ToolTip">
<Setter.Value>
<ToolTip>
<TextBlock Text="FOO"/>
</ToolTip>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
</Grid.Resources>
<Grid>
<!-- Others controls in here -->
<local:SomeControl />
</Grid>
In Window.xaml:
<Window.Resources>
<Style TargetType="local:SomeControl">
<Setter Property="ToolTip">
<Setter.Value>
<ToolTip>
<TextBlock Text="BAR"/>
</ToolTip>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<local:MyUserControl />
</Grid>
The result is it will display Foo when I want it to display Bar.
If I delete the ToolTip from the UserControl, the Window's style is used and it displays Bar like I expect.
Why is the Window style not overriding the UserControl explicit ToolTip property when present, but does when removed?
For the record, I've also tried changing MyUserControl to use a DynamicResource of the same x:Key names and had no affect.
Changing both to ToolTipService.ToolTip also had the same results.
EDIT: I fixed the example to demonstrate that even if the ToolTip is not set on a local level, it still doesn't override the style.
Unless someone can answer how to do override the children's style for the tooltip, I ended up making ToolTip object a dependency property on MyUserControl and passing it down to SomeControl.
The dependency property I made is called ExampleToolTip
MyUserControl.xaml:
<UserControl x:Name='MainControl'>
<UserControl.Resources>
<ToolTip x:Key="DefaultSomeControlToolTip">
<TextBlock Text="FOO"/>
<ToolTip>
</UserControl.Resources>
<Grid>
<local:SomeControl ToolTip="{Binding ExampleToolTip, ElementName=MainControl, TargetNullValue={StaticResource DefaultSomeControlToolTip}}"/>
</Grid>
</UserControl>
Window.xaml:
<Grid>
<local:MyUserControl>
<local:MyUserControl.ExampleToolTip>
<ToolTip>
<TextBlock Text="BAR"/>
</ToolTip>
</local:MyUserControl.ExampleToolTip>
</local:MyUserControl>
</Grid>
Now I can use MyUserControl with it's special "FOO" tooltip on SomeControl and Window has its "BAR" tooltip overriding it.
I am using ToggleButtons in the ToolBar and I want to get and use them in the UI Automation tests, but when I check AutomationElement.Current for these buttons, its ClassName property is Button, while I would expect ToggleButton
The xaml is not starightforward, so I mention it here :
<ToolBar ItemsSource="{Binding}"/>
for the type that's in the ItemsSource I have a DataTemplate:
<DataTemplate DataType="{x:Type myViewModelType}">
<ContentPresenter Content="{Binding}" ContentTemplate="{StaticResource MyToolBarElementTemplate}">
<ContentPresenter.Resources>
<Style TargetType="{x:Type ToggleButton}" BasedOn="{StaticResource ThisStyleSetsWidthAndHeight}"/>
</ContentPresenter.Resources>
</ContentPresenter>
</DataTemplate>
the style is defined as follows:
<Style TargetType="{x:Type ButtonBase}" x:Key="ThisStyleSetsWidthAndHeight">
<Setter Property="styles:AttachedProperties.ContentWidth" Value="32"/>
<Setter Property="styles:AttachedProperties.ContentHeight" Value="32"/>
</Style>
and the content template looks like this:
<DataTemplate x:Key="MyToolBarElementTemplate" DataType="{x:Type myViewModelType}">
<ToggleButton x:Name="AutomationIdThatIGetOk">
...
</ToggleButton>
</DataTemplate>
I am a bit new to Automation Framework, I guess it has to do with all these templates and styles, but is there any way to get the proper AutomationPeer instance created for this ToggleButton?
...but when I check AutomationElement.Current for these buttons, its ClassName property is Button, while I would expect ToggleButton
Your expectation is wrong because the ToggleButtonAutomationPeer class actually returns the string "Button" from its GetClassNameCore() method: https://referencesource.microsoft.com/#PresentationFramework/src/Framework/System/Windows/Automation/Peers/ToggleButtonAutomationPeer.cs,a58abe77888c16cd
So you are getting the proper instance.
I have 2 buttons, both of which are using a style to keep a consistent UI. However for 1 button, I would like to provide an image for, and the other just text.
I suppose I could create a new style, copy everything over, and the reformat it to my liking, but this seems like waste, is time consuming, and i think i would have to do it for each instance I wish to have a image on a button. I mean, that's fine, but I just want to know if there is an alternative that would make things more elegant.
I think I should somehow be able to push an 'arguement' or data to a style, either in or out of XAML to format the style, or something that would accomplish this (I'm sure the terminology is wrong).
Here is the Button Style:
<Style x:Key="Control_Button" TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<Image> <!-- Optional Image here --> </Image>
<TextBlock Name="btn" Text="{TemplateBinding Content}" Padding="16" VerticalAlignment="Center">
<TextBlock.TextDecorations>
<TextDecoration Location="Underline" />
</TextBlock.TextDecorations>
</TextBlock>
<!-- FIX ME: not underlined normally -->
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="TextBlock.IsMouseOver" Value="True">
<Setter TargetName="btn" Property="TextDecorations" Value="none" />
<!-- FIX ME: underlined on hover -->
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
What you are asking for is not possible without creating a custom control or user control.
What you should do though is setting the contents of the button the way you like. If you want only a string, you can set it directly:
<Button>my text</Button>
or with a binding:
<Button Content={Binding textProperty} />
To include an image in the button, add a panel as content, in this example I added a StackPanel, but you can also use a Grid or any other element:
<Button>
<Button.Content>
<StackPanel Orientation="Horizontal">
<Image Source="{Binding myImagePath}" />
<TextBlock Text="{Binding myText}" />
</StackPanel>
</Button.Content>
</Button>
WPF question. I'm not sure what to google for.
I have a usercontrol:
<UserControl x:Class="MyProj.MyControl"
x:Name="Self"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Button />
</UserControl>
I use it like this:
<local:MyControl Background="Green" />
But the background doesn't seem to change. It's because the background of the button hasn't changed. I want the background of the button to use the background of the usercontrol.
I suppose I could do this:
<UserControl x:Class="MyProj.MyControl"
x:Name="Self"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Button Background="{Binding Path=Background, ElementName=Self" />
</UserControl>
But I pretty much want all of the inherited properties from Control and ContentControl to apply to the button (ToolTip, BorderThickness, BorderBrush, etc).
So what can I do instead of this:
<UserControl x:Class="MyProj.MyControl"
x:Name="Self"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Button Background="{Binding Path=Background, ElementName=Self"
ToolTip="{Binding Path=ToolTip, ElementName=Self"
BorderThickness="{Binding Path=BorderThickness, ElementName=Self"
BorderBrush="{Binding Path=BorderBrush, ElementName=Self"
...
...
...
... />
</UserControl>
?
(Note: This is a small (the smallest I could manage, in fact) example of a larger UserControl which hosts many controls.)
Ugh. Well, short answer: You can't, at least not easily. XAML doesn't work quite like HTML/CSS does. The Button (and for that matter, pretty much any Control) does not inherit properties from their containers by default.
You could craft your own Button, etc controls that do inherit...alternatively, you might be able to declare a Style that applies to everything and attempts to grab any containing elements properties (i.e., via RelativeSource FindAncestor)...or you could do what you're doing here: set every property manually.
Example of the Style approach:
<Style TargetType="{x:Type Control}">
<Setter
Property="Background"
Value="{Binding (Control.Background), RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Control}}}"/>
</Style>
I want to take the highlight background off of the radtreeview. I created a style to do this, but I keep getting errors and exceptions such as "Items collection must be empty." If I comment out the style the application works fine, so I know that it is the cause of the problem. I am fairly new to WPF, and I am sure I just don't understand how to use styles yet.
Thanks for your help. Here is the code.
<Grid x:Name="LayoutRoot" Background="Salmon">
<telerik:RadTreeView x:Name="radTreeView" Margin="8" ItemsSource="{Binding Errors}" Background="Salmon" Style="{StaticResource treeStyle}">
<Style TargetType="{x:Type telerik:RadTreeViewItem}" x:Name="treeStyle">
<Setter Property="Focusable" Value="False"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Background" Value="{x:Null}"/>
<Setter Property="BorderBrush" Value="{x:Null}"/>
</Trigger>
</Style.Triggers>
</Style>
<telerik:RadTreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding SubItems}" >
<Grid Background="Salmon">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<TextBlock Text="{Binding Description}" IsHitTestVisible="False" />
<ListBox Grid.Row="1" ItemsSource="{Binding Messages}" Margin="20,0,0,0" BorderBrush="#00000000" BorderThickness="0" Background="Salmon" IsHitTestVisible="False" >
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Message}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</HierarchicalDataTemplate>
</telerik:RadTreeView.ItemTemplate>
</telerik:RadTreeView>
</Grid>
</UserControl>
If you know that this is not going to work, I was also trying to get rid of the highlight with the style code:
<Style TargetType="TreeViewItem">
<Style.Resources>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="#FFF"/>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightTextBrushKey}" Color="#000"/>
</Style.Resources>
</Style>
You get exceptions because your style tag is actually an item in the tree, and you have ItemsSource set.
Surround the style with <telerik:RadTreeView.ItemContainerStyle> tag.
This should solve the exception but it will not give you the result that you expect since the control template of the tree view item is actually showing another border that is not affected by the Background property. You will need to change the control template.
Telerik change the styles between releases, so giving you a template of a wrong version will probably won't help you.
But, you can go to the installation folder for Telerik and look for a folder called "Themes". There you'll find a solution with all the themes for telerik.
Choose the one that you use.
Find the resource dictionary for the tree view and copy the style and template for the item to your project.
Change xmlns definitions, make sure you have all the brushes and resources that the style depends upon.
Run to see that the style is ok.
In the template, find the VisualState with x:Name="MouseOver" and delete the storyboard inside it.