I am yet again struggling with UWP. It seems that I am unable to cascade Styles within Styles. Is this something else that is not allowed in UWP?
This is what I am trying to do...
<Style x:Key="MainMenuRadioButtonStyle" TargetType="RadioButton">
<Setter Property="Backgroud" Value="Grey"/>
<Style.Resources TargetType="TextBlock">
<Setter Property="Margin" Value="12,0,0,0"/>
</Style.Resources>
</Style>
However, VS2015 complains that the <Style.Resources> is invalid. I do not want to have to individually style the TextBlock within my RadioButton's content.
Cascading within styles not supported in UWP (or XAML in general). What you usually do is split up re-usable styles/properties and reference those.
<Thickness x:Key="MyMargin">"12,0,0,0"</Thickness>
<Style x:Key="MainMenuRadioButtonStyle" TargetType="RadioButton">
<Setter Property="Background" Value="Grey"/>
<Setter Property="Margin" Value="{StaticResource MyMargin}" />
</Style>
What you try to achieve is 'alter' the template of a RadioButton. You can find the full template here: https://msdn.microsoft.com/en-us/library/windows/apps/mt299147.aspx. If you dig into the template, you'll see this piece of code:
<ContentPresenter x:Name="ContentPresenter"
Content="{TemplateBinding Content}"
ContentTransitions="{TemplateBinding ContentTransitions}"
ContentTemplate="{TemplateBinding ContentTemplate}"
Margin="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Grid.Column="1"
AutomationProperties.AccessibilityView="Raw"
TextWrapping="Wrap" />
This is the part that's showing the actual content of your RadioButton and as you can see it's not a TextBlock, but a ContentPresenter (which will show text as if it was a TextBlock). The good news is that this control has a Margin property, which takes the value of the Padding property from the template. So to achieve what you want, you can simple fill in this property:
<Style x:Key="MainMenuRadioButtonStyle" TargetType="RadioButton">
<Setter Property="Background" Value="Grey"/>
<Setter Property="Padding" Value="{StaticResource MyMargin}" />
</Style>
If you want to change properties that are not available in the default template, then you'll have to create your own template.
Related
I want to have a different view with different screen in UWP, For example I have a grid with three columns in UWP app, inside the three columns it has two textboxes and button or other control. I want to change the Grid's column and row based on the screen size. When the screen size is more than 1000, the grid will have one row with three columns . when is more than 600 it will have two row, or it will have three row.
In UWP app, if you want to show different content/view based on the different screen size, we can use the AdaptiveTrigger to implement the adaptive UI.
The AdaptiveTrigger class has only two parameters: MinWindowWidth and MinWindowHeight. These two parameters allow us to switch state of window based on the different screen size.
For the detailed information, please check:
https://blogs.msdn.microsoft.com/cdndevs/2015/06/26/uwp-new-features-of-visual-state-manager-part-1/ .
In order to implement your scenario, I have created the following example, please try to refer to:
<Grid Background="Gray">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup>
<VisualState x:Name="ThreeColumns">
<VisualState.Setters>
<Setter Target="MyTextBox1.(Grid.Column)" Value="0"></Setter>
<Setter Target="MyTextBox1.(Grid.Row)" Value="0"></Setter>
<Setter Target="MyTextBox2.(Grid.Column)" Value="1"></Setter>
<Setter Target="MyTextBox2.(Grid.Row)" Value="0"></Setter>
<Setter Target="MyButton.(Grid.Column)" Value="2"></Setter>
<Setter Target="MyButton.(Grid.Row)" Value="0"></Setter>
<Setter Target="MyButton.Content" Value="This is one Row"></Setter>
</VisualState.Setters>
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="1000"></AdaptiveTrigger>
</VisualState.StateTriggers>
</VisualState>
<VisualState x:Name="TwoColumns">
<VisualState.Setters>
<Setter Target="MyTextBox1.(Grid.Column)" Value="0"></Setter>
<Setter Target="MyTextBox2.(Grid.Row)" Value="0"></Setter>
<Setter Target="MyTextBox1.(Grid.Column)" Value="1"></Setter>
<Setter Target="MyTextBox2.(Grid.Row)" Value="0"></Setter>
<Setter Target="MyButton.(Grid.Column)" Value="0"></Setter>
<Setter Target="MyButton.(Grid.Row)" Value="1"></Setter>
<Setter Target="MyButton.Content" Value="This is Two Row"></Setter>
</VisualState.Setters>
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="600"></AdaptiveTrigger>
</VisualState.StateTriggers>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid Height="500">
<Grid.RowDefinitions>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBox Name="MyTextBox1" Grid.Row="0" Height="50"></TextBox>
<TextBox Name="MyTextBox2" Grid.Row="1" Height="50"></TextBox>
<Button Name="MyButton" Background="Red" Content="This is Three Row" Grid.Row="2" Height="50"></Button>
</Grid>
The result:
I'm trying to convert old Window phone 7.5 Silverlight Application to new WinRT Universal application and I have problems with this pice of code:
<Style TargetType="Button">
<Setter Property="Visibility" Value="Collapsed"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Active}" Value="True">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
I used DataTrigger to set visibility of control based on binding value.
In Windows Phone 8.1 winrt app this functionality is out. I've tried with VisualStates to achieve same functionality but I can't figure it out. Can anyone help me or direct me with good example. I'm stuck here with this...
DataTriggers are not available currently in WinRT, you have couple of options instead:
use VisualStateManager,
use Behaviours managed API, for example like this:
<Button xmlns:i="using:Microsoft.Xaml.Interactivity"
xmlns:ic="using:Microsoft.Xaml.Interactions.Core">
<Button.Style>
<Style TargetType="Button">
<Setter Property="Visibility" Value="Collapsed"/>
</Style>
</Button.Style>
<i:Interaction.Behaviors>
<ic:DataTriggerBehavior Binding="{Binding Active}" Value="True" ComparisonCondition="Equal">
<ic:ChangePropertyAction PropertyName="Visibility" Value="Visible"/>
</ic:DataTriggerBehavior>
</i:Interaction.Behaviors>
</Button>
or you can just use binding with apropriate converter:
<Button Visibility="{Binding Active, Converter={StaticResource BoolToVisibility}}"/>
This a pretty basic question that I can't find a simple answer to anywhere online. In a Windows Store xaml/c# app, if I create a New Templated Control named CustomControl1.cs.
Here's the default template as defined in the Generic.xaml file:
<Style TargetType="local:CustomControl1">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:CustomControl1">
<Border>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I should be able to specify where child content lives by setting the Content property on the Border element above in either of the two following ways.
Specify content as Attribute
<Border Child="{TemplateBinding Content}" />
Specify content as Element
<Border>
<ContentPresenter ContentTemplate="{TemplateBinding ContentTemplate}"
Content="{TemplateBinding Content}" />
</Border>
But in either event, whenever I use the new control elsewhere, I'm unable to set the content property
Using this:
<local:CustomControl1>
<Button></Button>
</local:CustomControl1>
Gives off the two following errors:
Cannot add content to an object of type "CustomControl1"
The type 'CustomControl1' does not support direct content.
Make sure you derive your class from ContentControl and not just Control. This should resolve this for you. The default "Templated Control" item template is pretty generic to handle any case that folks might want, so if you want something more (in this case a Content control), just change to derive from ContentControl.
Hope this helps!
i have an image which i am adding it as content for a button. However the window is not getting rendered properly. How can i modify the XAML so that the button shape and color remains hidden but the traiangular image added to the button is displayed.
All you have to do is create a template with only an image and set the button template to it
<Style x:Key="ImageButtonStyle" TargetType="Button">
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Image Source="ImageSource.jpg"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Button Template="{DynamicResource ImageButtonStyle}"/>
Of course you need to redo all the animations like IsPressed, MouseOver, etc.
My ListBox is databound to 2 fields. The first is left aligned which is fine, the problem is with the second one which has to be right aligned. I tried using TextAlignment ="Right" and also HorizontalAlignment="Right", none of them worked.
Here is a sample code:
<ListBox x:Name="_listBox">
<ListBox.DataTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Margin="0,4,8,0">
<TextBlock Text="{Binding Path=ContainerNumber}" />
<TextBlock TextAlignment="Right" Text="{Binding Path=Content}"/>
</StackPanel>
</DataTemplate>
</ListBox.DataTemplate>
Any ideas?
Add to the StackPanel markup:
<StackPanel Orientation="Horizontal" HorizontalAlignment="Stretch" Margin="0,4,8,0">
This problem is that the StackPanel isn't using all the width available because it is by default aligned Left horizontally.
EDIT: Alternatively you need to style ListBoxItems:
<ListBox.Resources>
<Style x:Key="{x:Type ListBoxItem}" TargetType="{x:Type ListBoxItem}">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="HorizontalAlignment" Value="Stretch"/>
</Style>
</ListBox.Resources>
Hope this helps.