Silverlight: Why doesn't this style work? - silverlight

I'm using Silverlight 4. I have a button:
<Button Click="addTopicButton_Click">
<Image Source="/PlumPudding;component/Images/appbar.add.rest.png" />
</Button>
It looks fine. However, when I try to set its Content using a Style, no content appears:
<Style x:Name="AddButton" TargetType="Button">
<Setter Property="Content">
<Setter.Value>
<Image Source="/PlumPudding;component/Images/appbar.add.rest.png" />
</Setter.Value>
</Setter>
</Style>
<Button Click="addTopicButton_Click" Style="{StaticResource AddButton}" />
The button is empty. Why is this?

Its not a good idea to include UIElements such as Image in a style. Such an object is created only once when the style is put together during Xaml parsing. An important thing to understand about UIElements is that a single instance can only appear once in the Visual Tree. So even if your code worked it would only work for one button, any other button trying to use the same style would fail.
Instead you can use the ContentTemplate property like this:-
<Style x:Key="AddButton" TargetType="Button">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<Image Source="/PlumPudding;component/Images/appbar.add.rest.png" />
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
<Button Click="addTopicButton_Click" Style="{StaticResource AddButton}" />
The button is now given a DataTemplate that it uses to construct the child element that renders the content of the button. Each button will therefore construct its own independent instance of an Image control.

You should use x:Key to name your Style element rather than x:Name

Your code requires two changes.
Changed x:Name to x:Key, And refer to it when you want to use it, using StaticResource.
Change this
<Setter.Value>
<Image Source="whatever..." />
</Setter.Value>
to this,
<Setter.Value>
<DataTemplate>
<Image Source="whatever..." />
</DataTemplate>
</Setter.Value>
See if it helps you!

Related

Excess border selection in WPF's Lisbox [duplicate]

I have a ListBox in which each item is a StackPanel. The StackPanel consist of an Image and a TextBlock below it:
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="10">
<Image>
<Image.Source>
<BitmapImage UriSource="{Binding Path=ImageFilePath}"/>
</Image.Source>
</Image>
<TextBlock Text="Title" TextAlignment="Center"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
It looks like this:
When the user select an item, I get the default blue rectangle that surround the StackPanel:
Now, I want to make a different border for the selected-item, but I want it to surround only the image.
I know how to make a control template and put a custom border around the ContentPresenter, but this, of course, will surround the whole StackPanel, not only the Image.
I don’t know if making changes to the ContentPresenter is possible, and if it is a good idea at all. If there is other way to achieve the look I want, it will be fine as well.
Right, the ListBox's own ContentPresenter isn't helpful for what you're doing. You want to a) eliminate the ListBox's own selection visuals and b) replace them with something more suitable in the DataTemplate for your items.
The default selection visual is applied by the default template for ListBoxItem. So replace that template. Using a Style in the resources for your ListBox, apply your own control template to ListBoxItem. Not much to it, just present the content and don't provide a selection background. Then you handle the selection visuals with a trigger in your data template, where your image and your label are defined and you can apply changes to one and not the other. The below example works for me.
Note that there's some fiddling with the HorizontalAlignment on the Border element to make it cling to the Image element within it. Also, I wrote a quickie test viewmodel whose Items property is called Items; I assume this is not the name of the collection member you're using to populate your own ListBox.
<ListBox
Margin="8"
ItemsSource="{Binding Items}"
>
<ListBox.Resources>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Grid>
<ContentPresenter />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.Resources>
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Border
x:Name="HighlightBorder"
BorderThickness="4"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Margin="10"
>
<Border.Style>
<Style TargetType="Border">
<!-- MUST set default BorderBrush via a style, if you set it at all.
As an attribute on the Border tag, it would override the effects of
the trigger below.
-->
<Setter Property="BorderBrush" Value="Transparent" />
</Style>
</Border.Style>
<Image Source="{Binding ImageFilePath}" />
</Border>
</Grid>
<DataTemplate.Triggers>
<DataTrigger
Binding="{Binding IsSelected, RelativeSource={RelativeSource AncestorType=ListBoxItem}}"
Value="True">
<Setter TargetName="HighlightBorder" Property="BorderBrush" Value="Orange" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

Access ControlTemplate components (windows 8 app)

I would like to combine some UI elements into a Control, and then access them by code. However I can't figure it out.
The control template:
<Page.Resources>
<Style x:Key="GridViewStyle1" TargetType="GridView">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="GridView">
<Grid>
<TextBox x:Name="theTextBox" Text="The Text" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Page.Resources>
And a reference to the Template:
<GridView x:Name="myGridView1" Style="{StaticResource TileControl}"/>
So what I'm looking for is something like this for example:
myGridView1.Style.Template.Gridview.theTextBox.Text
But I can't find it. Any idea how I can do that? Or maybe I'm on the wrong track since it shouldn't be so complicated?
To retrieve ControlTemplate-generated element you can use something like (after the template has been applied to the control)
yourcontrol.Template.FindName("ControlElementTemplateToFind")
See also msdn

Silverlight Style control

I have added a check box in silverlight style.
<Style x:Key="DataGridColumnHeaderStyle" TargetType="dataprimitives:DataGridColumnHeader">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<CheckBox Content="Add to Template" x:Name="chkAllDelimited" Checked="chkAllDelimited_Checked" Unchecked="chkAllDelimited_Unchecked"
VerticalAlignment="Center" IsChecked="false" HorizontalAlignment="Center" HorizontalContentAlignment="Left"/>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
How to get this x:Name="chkAllDelimited" control in the code behind?
Thanks in advance...
Embedded inside a style as is you can't. An option you do have is adding an OnLoad event to the checkbox which would fire in your code behind, where you could then cast the sender to a CheckBox object and access it, store it in a local variable, or whatever you'd like to do with it.

Control Template for a button to be displayed as an image.png

Iam have been working on the control templates since few days,iam successfull in changing a button to the ellipse ,but when iam about to create a control template for button to be displyed as a image,i am not Successful.If any one can know it ,please help me out.
The following xaml shows a button with a ControlTemplate consisting of only an image:
<Button>
<Button.Template>
<ControlTemplate>
<Image Source="/arrow_down_blue.png" Stretch="None" />
</ControlTemplate>
</Button.Template>
</Button>
If you cannot get it to work, make sure that the path to your image is valid. The easiest way is to add the image to your solution and mark it as Resource, by right clicking the image in the solution explorer and setting Build Action to Resource. You can then reference the image by using a so called pack URI on the form:
/FolderName/OtherFolderName/FileName.png
The path above is relative to the root of the current project.
The ControlTemplate could also be set though a Style or by setting the Template property of the button to a StaticResource:
<Grid>
<Grid.Resources>
<ControlTemplate x:Key="ImageButtonTemplate">
<Image Source="/arrow_down_blue.png" Stretch="None" />
</ControlTemplate>
<Style TargetType="Button" x:Key="ImageButtonStyle">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Image Source="/arrow_down_blue.png" Stretch="None" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Grid.Resources>
<StackPanel>
<Button Template="{StaticResource ImageButtonTemplate}" />
<Button Style="{StaticResource ImageButtonStyle}" />
</StackPanel>
</Grid>
An example of how to add triggers to your control template can be found in this question.

WPF: How to style or disable the default ContextMenu of a TextBox

Apparantly when users right-click in our WPF application, and they use the Windows Classic theme, the default ContextMenu of the TextBox (which contains Copy, Cut and Paste) has a black background.
I know this works well:
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<TextBox ContextMenu="{x:Null}"/>
</Page>
But this doesn't work:
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Page.Resources>
<Style x:Key="{x:Type TextBox}" TargetType="{x:Type TextBox}">
<Setter Property="ContextMenu" Value="{x:Null}"/>
</Style>
</Page.Resources>
<TextBox/>
</Page>
Does anyone know how to style or disable the default ContextMenu for all TextBoxes in WPF?
To style ContextMenu's for all TextBoxes, I would do something like the following:
First, in the resources section, add a ContextMenu which you plan to use as your standard ContextMenu in a textbox. e.g.
<ContextMenu x:Key="TextBoxContextMenu" Background="White">
<MenuItem Command="ApplicationCommands.Copy" />
<MenuItem Command="ApplicationCommands.Cut" />
<MenuItem Command="ApplicationCommands.Paste" />
</ContextMenu>
Secondly, create a style for your TextBoxes, which uses the context menu resource:
<Style TargetType="{x:Type TextBox}">
<Setter Property="ContextMenu" Value="{StaticResource TextBoxContextMenu}" />
</Style>
Finally, use your text box as normal:
<TextBox />
If instead you want to apply this context menu to only some of your textboxes, do not create the style above, and add the following to your TextBox markup:
<TextBox ContextMenu="{StaticResource TextBoxContextMenu}" />
Hope this helps!
Bizarre. ContextMenu="{x:Null}" doesn't do the trick.
This does, however:
<TextBox.ContextMenu>
<ContextMenu Visibility="Collapsed">
</ContextMenu>
</TextBox.ContextMenu>
Due to a late bug report we discovered that we cannot use the ApplicationComands Cut Paste and Copy directly in a partial trusted application. Therefor, using these commands in any Commmand of your controls will do absolutely nothing when executed.
So in essence Brads answer was almost there, it sure looked the right way i.e. no black background, but did not fix the problem.
We decided to "remove" the menu based on Brads answer, like so:
<ContextMenu x:Key="TextBoxContextMenu" Width="0" Height="0" />
And use this empty context menu like so:
<Style TargetType="{x:Type TextBox}">
<Setter Property="ContextMenu" Value="{StaticResource TextBoxContextMenu}" />
</Style>
Doesn't matter, if you do not provide a key, it will use the TargetType as key just the same way my example uses :)
Taken from MSDN on Style:
Setting the TargetType property to the TextBlock type without
setting an x:Key implicitly sets the x:Key to {x:Type TextBlock}. This also means that if you > > give the above Style an x:Key value of anything other than {x:Type TextBlock}, the Style
would not be applied to all TextBlock elements automatically. Instead,
you need to apply the style to the TextBlock elements explicitly.
http://msdn.microsoft.com/en-us/library/system.windows.style.targettype.aspx
This is way is what I always use:
<TextBox x:Name="MyTextbox">
<TextBox.ContextMenu>
<ContextMenu Visibility="Hidden"/>
</TextBox.ContextMenu>
</TextBox>
And also can use:
MyTextbox.ContextMenu.Visibility = Visibility.Hidden;
MyTextbox.ContextMenu.Visibility = Visibility.Visble;
Try removing the x:Key attribute from the Style resource, leaving TargetType. I know, you're supposed to have that x:Key for a resource, but if you have it along with your TargetType the Key prevails.
Here's a sample style that I use in a project to skin all tooltips in one of my apps (this is in App.Resources--notice, no Key)
<Style
TargetType="{x:Type ToolTip}">
<Setter
Property="Template">
<Setter.Value>
<ControlTemplate
TargetType="{x:Type ToolTip}">
<Grid
Width="{TemplateBinding Width}"
Height="{TemplateBinding Height}">
<Rectangle
RadiusX="9"
RadiusY="9"
Stroke="LightGray"
StrokeThickness="2">
<Rectangle.Fill>
<RadialGradientBrush>
<GradientStop />
<GradientStop
Color="FloralWhite"
Offset="0" />
<GradientStop
Color="Cornsilk"
Offset="2" />
</RadialGradientBrush>
</Rectangle.Fill>
</Rectangle>
<ContentPresenter
Margin="6 4 6 4" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

Resources