Xamarin forms access element outside a ControlTemplate - xaml

I'm trying to find out a way to access a named element outside a ControlTemplate, or viceversa, access a named element inside a ControlTemplate from outside, from XAML (not code behind).
Let's suppose I have the following code:
<ResourceDictionary>
<ControlTemplate x:Key="MyControlTemplate">
<views:MyView x:Name="MyViewName">
<views:MyView.Triggers>
<DataTrigger TargetType="views:MyView" Binding="{Binding MyProperty}" Value="True">
<Setter TargetName="MyCollectionView" Property="IsEnabled" Value="False"></Setter>
</DataTrigger>
</views:MyView.Triggers>
</views:MyView>
</ControlTemplate>
<ControlTemplate x:Key="MyOtherControlTemplate">
<views:MyOtherView x:Name="MyViewName"></views:MyView>
</ControlTemplate>
</ResourceDictionary>
<CollectionView x:Name="MyCollectionView">
...
</CollectionView>
<TemplatedView
Grid.Row="1"
ControlTemplate="{StaticResource MyControlTemplate}"/>
<TemplatedView
Grid.Row="1"
ControlTemplate="{StaticResource MyOtherControlTemplate}"/>
This code is inside a ContentView. Which shows, depending on the selected item in the CollectionView, a view (MyView) or another view (MyOtherView). If MyProperty (which is a property inside the view MyView) is True, then I want the collectionView to be disabled. Since MyView is declared inside the ControlTemplate, I can't manage it to access to MyCollectionView
Where MyProperty is a boolean inside MyView ViewModel.
This code throws ArgumentNullException: Value cannot be null. Parameter name: targetObject.
Apparently, MyCollectionView is unknown inside the ControlTemplate
I have also tried to reference to MyView's name in a DataTrigger of MyCollectionView and it has no result.
Can anyone help me?

Related

Styling for ListBox, ListView and GridView Items

The default colors for these controls seems to be similar to the Windows theme colors. How do you change the hover, selected, selected hover and pressed colors (code or XAML)? The following isn't working for the ListView:
<ListView>
<ListViewItemPresenter
PointerOverBackground="#99CEEA"
SelectedPressedBackground="#72BFE9"
SelectedBackground="#72BFE9"
SelectedPointerOverBackground="#99CEEA"
/>
In your VS/Blend Designer, right click on your ListView and select
Edit Additional Templates > Edit Generated Item Container
(ItemContainerStyle) > Edit a Copy...
In the popup window above, if you want this style to be applied to all your ListViewItem, select Apply to all otherwise just give it a name.
I'd recommend to create a new Resource dictionary for storing all ListView related styling. To do so, just hit the New... button and give the resource dictionary a name (e.g. ListViewStyles.xaml).
Finally, hit the OK button and you now have a fully generated style.
In the style's ControlTemplate, you can locate the ListViewItemPresenter control and update its colors accordingly.
The ListViewItemPresenter was in the wrong place in the XAML. Change this:
<ListView>
<ListViewItemPresenter
PointerOverBackground="#99CEEA"
SelectedPressedBackground="#72BFE9"
SelectedBackground="#72BFE9"
SelectedPointerOverBackground="#99CEEA"
/>
</ListView>
to this:
<ListView>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListViewItem">
<ListViewItemPresenter
PointerOverBackground="#99CEEA"
SelectedPressedBackground="#72BFE9"
SelectedBackground="#72BFE9"
SelectedPointerOverBackground="#99CEEA" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListView.ItemContainerStyle>
<ListView>

UWP ResourceDictionary Style Error: The parameter is incorrect

I'm making a ResourceDictionary of common styles that are used throughout my application and one of them is:
<Style x:Key="ME_BASE_AppbarButtonSaveStyle"
TargetType="AppBarButton">
<Setter Property="Label"
Value="Save" />
<Setter Property="ToolTipService.ToolTip"
Value="Save" />
<Setter Property="Icon">
<Setter.Value>
<FontIcon FontFamily="Segoe MDL2 Assets"
Glyph="" />
</Setter.Value>
</Setter>
</Style>
It's all ok if I apply the style only one AppbarButton on the Page, but if I want to have two buttons with the same style, I get the following error:
The parameter is incorrect
It's of ok (no error) if I remove the icon property out of the style...
But that's kind of missing the point...
Anyone experienced something similar? Perhaps...
Thank you for all the help.
Error HRESULT E_Fail has been returned from a call to a COM component.
This error will occurred when you use this style for the second AppBarButton. This error usually happens when a reference to a style or an event handler that does not exist or is not with the context of the XAML, you can see the exception information of your problem:
If you read this document: XAML resources must be shareable, you will find:
Custom types used as resources can't have the UIElement class in their inheritance, because a UIElement can never be shareable (it's always intended to represent exactly one UI element that exists at one position in the object graph of your runtime app).
Whether a Icon property of AppBarButton or a FontIcon derives from UIElement, so I guess this is the reason why can't this property be styled in the resource dictionary.
Besides, I will consider if this is a right direction to define the Icon property for each AppBarButton in the style, normally I'd like give each button a different icon as content.
But if you insist to do this, I can provide you a workaround method by defining the Content of the AppBarButton, this is the construction of your AppBarButton:
You use a FontIcon as the content of the AppBarButton, so we can modify your style like this:
<Style x:Key="ME_BASE_AppbarButtonSaveStyle" TargetType="AppBarButton">
<Setter Property="Label" Value="Save" />
<Setter Property="ToolTipService.ToolTip" Value="Save" />
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<FontIcon FontFamily="Segoe MDL2 Assets"
Glyph="" />
</DataTemplate>
</Setter.Value>
</Setter>
</Style>

UWP Why does a style not apply to TargetTypes in DataTemplate?

Given a style in a Page.Resource:
<Style x:Name="ItemTitle" TargetType="TextBlock">
<Setter Property="FontSize" Value="16"></Setter>
<Setter Property="FontWeight" Value="Bold"></Setter>
</Style>
It is correctly applied to any regular TextBlock on the same page.
However, when I use a DataTemplate for an Item in a GridView on that page, this style does not apply.
<DataTemplate x:Key="Output" x:DataType="vm:Output">
<TextBlock Text="{x:Bind Text}"></TextBlock>
</DataTemplate>
It does work when I apply the style explicitly on the DataTemplate, e.g.:
<DataTemplate x:Key="Output" x:DataType="vm:Output">
<TextBlock Style="{StaticResource ItemTitle}" Text="{x:Bind Text}"></TextBlock>
</DataTemplate>
Does anyone know what's up?
It's expected and intentional. If it doesn't derive from Control (like DataTemplate) then it won't inherit an implicit style unless they're in the application resource dictionaries as global defaults.
Or more specifically;
Templates are viewed as an encapsulation boundary when looking up an implicit style for an element which is not a subtype of Control.
Hope this helps. Cheers.
Addendum:
If it's a situation where you have a lot of the same element nested in a Template you can just set it once and allow it to inherit to all the nested controls of the type like (in pseudo);
<Parent>
<Parent.Resources>
<Style TargetType="TextBlock" BasedOn="{StaticResource ItemTitle}"/>
<Parent.Resources>
<!-- These will all inherit the Style resource now,
without explicit style setting individually. -->
<TextBlock/>
<TextBlock/>
<TextBlock/>
</Parent>

XAML Binding a ComboBox Style Setter for Background to a memory object's Field value

I have a ComboBox, bound to a list of objects. I can get the objects to fill the drop down just fine. I am trying to set the background color for each object in the items list of the dropdown. I can set any color for all of them easily in the below style code.
What I want to do is Bind the Background Color Value to the KeyColorValue field of my Key object.
Here is my XAML:
DisplayMemberPath="Name"
HorizontalAlignment="Left"
Margin="300,103,0,0"
VerticalAlignment="Top"
Width="186"
SelectionChanged="roleBoundSelector_SelectionChanged" >
<ComboBox.ItemContainerStyle>
<Style TargetType="ComboBoxItem">
<Setter Property="Background"
Value = "{Binding Path=KeyColorValue}" />
(If I put a color in here it works just fine...need to bind to the KeyColorValue of the MyKeys Object.)
Try this inside your style:
<Setter Property="Background">
<Setter.Value>
<Binding RelativeSource="{RelativeSource Self}" Path="DataContext.KeyColorValue"/>
</Setter.Value>
</Setter>
The DataContext of each ComboBoxItem is an object contained in the List that is feeding the ItemsSource of the ComboBox.
Let me know if this was of any help, regards!

How to disable ListView's Hover and Tile effects?

I want to disable Tile effect that is some kind of pushed effect and hover background color effect of ListView control, how can i do that?
Thanks
After some googling I found that the highlighting happens in the ListViewItemPresenter, which turns out to be pretty hidden. It's located inside the ControlTemplate of an ListViewItem, which is the ItemContainer for the ListView. The simplest way I've found to disable the effect is to simply override this ControlTemplate:
<ListView>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<ContentPresenter/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListView.ItemContainerStyle>
<TextBlock Text="List Item" />
...
<TextBlock Text="List Item" />
source: https://blog.jonstodle.com/uwp-listview-without-highlighting-and-stuff/
Look at this question:
Disable cross-slide selection for a listview
You can also make changes to the template to remove any visual states and adornments - go to the designer and right click your ListView/Edit Additional Templates/Edit Generated Item Container (ItemContainerStyle)/Edit a Copy... - that will extract the template you can modify using your preferred method.