I have many XAML TextBlock which looks like this:
<TextBlock Text="{Binding InspectionCount}" Style="{StaticResource FilterText}">
<i:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="Tapped">
<core:InvokeCommandAction Command="{Binding SetModeToAll}" />
</core:EventTriggerBehavior>
</i:Interaction.Behaviors>
</TextBlock>
I want to reduce amount of XAML code and write something like this:
<MyTextBlock Text="{Binding InspectionCount}"
Style="{StaticResource FilterText}"
Command="{Binding SetModeToAll}" />
I know only one way to do such things - create the new class (which is inherited from TextBlock), add AttachedProperty (Command) to new class, and create a Style for a new class.
But looks like I cannot inherit my class from TextBlock:
public sealed class FilterTextBlock : TextBlock
Cannot inherit from sealed class TextBlock
Why I can not do it? May be there is other way to do what I wish ?
I have discovered that the following WORKS. and solves the question from many places, I will start answering, Try the following!
<Page
x:Class="Example1.ListBoxTest"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Example1"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:i="using:Microsoft.Xaml.Interactivity"
xmlns:core="using:Microsoft.Xaml.Interactions.Core"
mc:Ignorable="d">
<Page.Resources>
<i:BehaviorCollection x:Key="behaviors">
<core:EventTriggerBehavior EventName="Tapped">
<core:InvokeCommandAction Command="{Binding SetModeToAll}" />
</core:EventTriggerBehavior>
</i:BehaviorCollection>
<Style TargetType="TextBlock" x:Key="textblockstyle">
<Setter Property="i:Interaction.Behaviors" Value="{StaticResource behaviors}">
</Setter>
</Style>
</Page.Resources>
<Grid x:Name="LayoutRoot" Background="Transparent">
<TextBlock Text="Testing" Foreground="Red" FontSize="20" Style="{StaticResource textblockstyle}">
</TextBlock >
</Grid>
It is curious, if I set the behaviors inside the propery i:Interaction.Behaviors does not work but in this way the Command is called!!
Please tell me it works you too!
Just use:
<Setter Property="i:Interaction.Behaviors">
<Setter.Value>
<i:BehaviorCollection>
<MyCustomBehavior />
</i:BehaviorCollection>
</Setter.Value>
</Setter>
inside the <Style TargetType="TextBlock"> tag.
Don't forget to include xmlns:i="using:Microsoft.Xaml.Interactivity" at the top of the page.
Related
This has come up a few times, and I've been struggling with it all day in a UWP app.
My specific issue was that I was using x:Bind inside a ContentTemplate that was inside a DataTemplate:
<DataTemplate x:DataType="IFactionMember">
<Button Command="{x:Bind **Property of IFactionMember**}"> // Good
<Button.Template>
<ControlTemplate TargetType="Button">
<Grid Padding="10,0">
<TextBlock Text="{x:Bind **Property of IFactionMember**}" /> // Bad
</Grid>
</ControlTemplate>
</Button.Template>
</Button>
</DataTemplate>
You cannot do this :(
You could use {Binding} instead for your scenario, for example:
<ListView x:Name="listview" ItemsSource="{x:Bind members}">
<ListView.ItemTemplate>
<DataTemplate x:DataType="local:IFactionMember">
<Button >
<Button.Template>
<ControlTemplate TargetType="Button" >
<Grid Padding="10,0">
<TextBlock Text="{Binding testtext}" />
</Grid>
</ControlTemplate>
</Button.Template>
</Button>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
x:bind lacks some of the features of {Binding}, in x:Bind, Path is rooted at the Page by default, not the DataContext, it seems like if you are using x:bind here, it will try to find the property at the MainPage, so that it will not find the correct property.
My DashBoardSimpleCountObject has 2 values: MyName and MyValue.
I use an ObservableCollection<DashboardSimpleCountObject> called MyData.
I want to show a picture, as long as MyValue is null.
However, the picture ("loading") is only shown at the last item of my ObservableCollection (no matter, how many items are in there). As soon as a MyValue is set (with anything other than null), it is automatically updated and shown correctly - that works fine at all items.
<ItemsControl x:Name="_control" ItemsSource="{Binding MyData}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Margin="25">
<Label FontSize="14" Content="{Binding MyName}" />
<Label Margin="0,25" HorizontalContentAlignment="Right" FontSize="29" FontWeight="ExtraBold" Foreground="{Binding MyColor}">
<Label.Style>
<Style TargetType="{x:Type Label}">
<Setter Property="Content" Value="{Binding MyValue}" />
<Style.Triggers>
<DataTrigger Binding="{Binding MyValue}" Value="{x:Null}">
<Setter Property="Content">
<Setter.Value>
<Image Width="32" Height="32" Source="{DynamicResource loading}" />
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</Label.Style>
</Label>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
What am I doing wrong?
Thank you very much in advance! :)
It seems, the nature of DynamicResource causes this issue.
Simply changing DynamicResource to StaticResource did the trick.
So, the DataTrigger worked just fine from the beginning. The image simply did only show up once due to being loaded as a DynamicResource.
I am trying to create a button Style that I can use for a "Lookup" button throughout my UWP app. However, the icon only appears on the first button on the screen. I tried this solution using templates, but it is not working for me. Thanks for the help.
Code:
<Page.Resources>
<ControlTemplate x:Key="FindSymbolTemplate">
<SymbolIcon Symbol="Find" Foreground="White" />
</ControlTemplate>
<Style TargetType="Button" x:Key="LookupButton">
<Setter Property="Content">
<Setter.Value>
<ContentControl Template="{StaticResource FindSymbolTemplate}" />
</Setter.Value>
</Setter>
</Style>
</Page.Resources>
....
<Button x:Name="tourNumLookup"
Style="{StaticResource LookupButton}"
Grid.Column="1"
Margin="10,0"
VerticalAlignment="Center" />
....
<Button x:Name="customerIdLookup"
Style="{StaticResource LookupButton}"
VerticalAlignment="Center"
Grid.Column="1"
Grid.Row="1"
Margin="10,0" />
The two buttons in the UI. Only the first has the SymbolIcon content.
#Romasz's solution absolutely works, but what if you want a lightly different Foreground on the SymbolIcon inside another Button?
Here's a potentially more flexible way that I normally go with.
First let's create a base Style that holds some default values for all the icons.
<Style x:Key="Style-Icon-Base"
TargetType="ContentControl">
<!-- If you don't specify the Foreground, it will use its ancestor's -->
<!--<Setter Property="Foreground"
Value="White" />-->
<Setter Property="HorizontalContentAlignment"
Value="Center" />
<Setter Property="VerticalContentAlignment"
Value="Center" />
<Setter Property="Width"
Value="20" />
<Setter Property="Height"
Value="20" />
<Setter Property="Padding"
Value="0" />
</Style>
Then we create a new icon Style which inherits from the one above. Note within the ControlTemplate I have used TemplateBinding to make property values dynamic. TemplateBinding isn't available inside a DataTemplate.
<Style x:Key="Style-Icon-Find"
BasedOn="{StaticResource Style-Icon-Base}"
TargetType="ContentControl">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ContentControl">
<!--
'cause you cannot change the size of the SymbolIcon, we insert a Viewbox here,
otherwise you don't need it.
-->
<Viewbox Margin="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
<SymbolIcon Symbol="Find"
Foreground="{TemplateBinding Foreground}" />
</Viewbox>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
This way you have created a highly reusable icon Style, to use it, have a look at the following Buttons:
<StackPanel Orientation="Horizontal"
HorizontalAlignment="Center">
<Button Margin="4"
Padding="8"
BorderBrush="LightBlue">
<ContentControl Width="36"
Height="36"
Foreground="DarkCyan"
Style="{StaticResource Style-Icon-Find}" />
</Button>
<!-- Note how I defined the Foreground at the Button level and it flows down to the icon -->
<Button Foreground="DarkGoldenrod"
Margin="4">
<StackPanel Orientation="Horizontal">
<ContentControl Style="{StaticResource Style-Icon-Find}"
Width="16"
Height="16" />
<TextBlock Text="Search"
VerticalAlignment="Center"
Margin="8,0,0,0" />
</StackPanel>
</Button>
<Button Margin="4"
Padding="4">
<ContentControl Style="{StaticResource Style-Icon-Find}" />
</Button>
</StackPanel>
And they look like:
Generally UI elements can be used once (or saying different - have only one parent) - this is probably why it only works for the first button in your case. One solution may be to define DataTemplate and use it as ContentTemplate, so each button creates its own icon:
<Page.Resources>
<DataTemplate x:Key="FindTemplate">
<SymbolIcon Symbol="Find" Foreground="White" />
</DataTemplate>
</Page.Resources>
...
<Button x:Name="tourNumLookup" ContentTemplate="{StaticResource FindTemplate}"
Grid.Column="1" Margin="10,0" VerticalAlignment="Center" />
<Button x:Name="customerIdLookup" ContentTemplate="{StaticResource FindTemplate}"
VerticalAlignment="Center" Grid.Column="1" Grid.Row="1" Margin="10,0" />
You don't need to create ControlTemplate to reuse the icon. You can simply put this SymbolIcon to the resource dictionary and use as StaticResource for the buttons' Content.
<Page.Resources>
<SymbolIcon x:Key="FindSymbol" Symbol="Find" Foreground="White" />
</Page.Resources>
<Button x:Name="tourNumLookup"
Content="{StaticResource FindSymbol}"
Grid.Column="1"
Margin="10,0"
VerticalAlignment="Center" />
<Button x:Name="customerIdLookup"
Content="{StaticResource FindSymbol}"
VerticalAlignment="Center"
Grid.Column="1"
Grid.Row="1"
Margin="10,0" />
UPDATE
BTW this is possibly a bug in the UWP platform, because I tried the following code and only the first Button rendered the icon at desing time and none of the at runtime.
<Page.Resources>
<SymbolIcon x:Key="FindSymbol" Symbol="Find" Foreground="White" />
<Style TargetType="Button" x:Key="LookupButton">
<Setter Property="Content" Value="{StaticResource FindSymbol}"/>
</Style>
</Page.Resources>
<StackPanel>
<Button x:Name="tourNumLookup"
Style="{StaticResource LookupButton}"
Margin="10,0"
VerticalAlignment="Center" />
<Button x:Name="customerIdLookup"
Style="{StaticResource LookupButton}"
VerticalAlignment="Center"
Margin="10,0" />
</StackPanel>
I tried to assign the Setter's Value directly but I got the same result. And also tried with FontIcon.
I am kind of beginner in UWP Platform and I am building an app using template 10. I have used GridView for a particular page, but the problem is that the GridView shows its borders when you hover over it or select its item. Like this:
I want the border not to show up whenever the user hovers over it or selects a GridView item.
My XAML Code is:
<Page
x:Class="Sample.Views.Category"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Sample.Views"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:data="using:Sample.ViewModels"
xmlns:controls="using:Template10.Controls"
mc:Ignorable="d">
<Page.Resources>
<DataTemplate x:DataType="data:CategoryViewModel" x:Key="CategoryDataTemplate">
<StackPanel HorizontalAlignment="Center" Margin="10,0,20,10">
<Image Width="150" Source="{x:Bind IconFile}" />
<TextBlock FontSize="16" Text="{x:Bind Category}" HorizontalAlignment="Center" />
<!--<TextBlock FontSize="10" Text="{x:Bind Author}" HorizontalAlignment="Center" />-->
</StackPanel>
</DataTemplate>
</Page.Resources>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!-- header -->
<controls:PageHeader x:Name="pageHeader" Frame="{x:Bind Frame}" Text="Category Page" Grid.Row="0" Grid.ColumnSpan="2">
<!-- place stretched, across top -->
<RelativePanel.AlignTopWithPanel>True</RelativePanel.AlignTopWithPanel>
<RelativePanel.AlignRightWithPanel>True</RelativePanel.AlignRightWithPanel>
<RelativePanel.AlignLeftWithPanel>True</RelativePanel.AlignLeftWithPanel>
</controls:PageHeader>
<GridView Grid.Row="2" >
<GridView ItemsSource="{x:Bind Categories}"
IsItemClickEnabled="True"
ItemClick="GridView_ItemClick"
ItemTemplate="{StaticResource CategoryDataTemplate}" >
</GridView>
</GridView>
</Grid>
This is not a Template 10 question, but here's the answer:
<GridView>
<GridView.ItemContainerStyle>
<Style TargetType="GridViewItem">
<Setter Property="Margin" Value="0,0,4,4" />
<Setter Property="Background" Value="Transparent"/>
<Setter Property="TabNavigation" Value="Local"/>
<Setter Property="IsHoldingEnabled" Value="True"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="GridViewItem">
<ContentPresenter />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GridView.ItemContainerStyle>
</GridView>
Best of luck.
Try setting the gridview BorderThickness to 0, and brush to Transparent (assuming the thickness didn't work)
https://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.xaml.controls.gridview.aspx
Here is a link to the properties for the gridview control in XAML.
since you said you're a beginner, try messing around with the different properties and since you have a nested gridview inside a gridview (not sure why) try setting it on both of them.
e.g.:
<GridView Grid.Row="2" BorderThickness="0">
This problem is about the listbox itself and not it's cells. If I put listbox into a viewbox, and click on an item, the whole listbox will be surrounded with a 1px border. I do not want that, because it is ugly. How to remove this border?
Details:
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Viewbox Grid.Row="1" Stretch="Uniform">
<StackPanel Orientation="Horizontal" Margin="0,20,0,20">
<Grid Width="200">
<ListBox ItemsSource="{Binding Rajzelemek}" Background="{x:Null}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<ContentControl Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" Content="{Binding Ikonja}" Width="25" Height="25" VerticalAlignment="Center" />
<TextBlock Text="{Binding}" VerticalAlignment="Center" Foreground="{ThemeResource ApplicationForegroundThemeBrush}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
</Grid>
</StackPanel>
</Viewbox>
</Grid>
If I comment the <Viewbox Grid.Row.... part, everything is fine, but not scaled. I want stuff to get scaled, well that is why I use the viewbox, but I do not want this border:
The code above was put on a metro BlankPage1 too, and made the same thing.
I think you're looking for what's in the ListBoxItem template wherein there's a Rectangle acting as a Focus Visual, if you check out the default template you'll see it with a default brush attributed to it (FocusVisualWhiteStrokeThemeBrush) which you could either change in the template, or provide your own resource for it to find before it hits the default dictionaries like;
<SolidColorBrush x:Key="FocusVisualWhiteStrokeThemeBrush" Color="Transparent" />
Hope this helps.
EDIT
Sorry I was going by the picture you have, thought it was the item. In any case since your ViewBox is the culprit you just need to interact with the Border control within it >like you showed in a previous post of your own< where you're the one making that border. Something like;
<Viewbox>
<Viewbox.Resources>
<Style TargetType="Border">
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="BorderThickness" Value="0" />
</Style>
</Viewbox.Resources>
...
</ViewBox>