In Xamarin Forms, an effect can be added in XAML, like this:
<Label ... >
<View.Effects>
<effects:MyGlowEffect Radius="10" Color="White"/>
</View.Effects>
</Label>
GOAL:
I want this effect to only be active when a boolean in my ViewModel is true. E.g. the equivalent of (fake code - no such property "IsEnabled"):
<effects:MyGlowEffect Radius="10" Color="White" IsEnabled="{Binding EnableEffect}"/>
How can I accomplish this?
I thought of using a Trigger, but I don't understand how a trigger could attach/detact an Effect. Nor how to have the Effect written in XAML, if it is sometimes attached and sometimes not.
I'm not looking for an answer that involves a custom renderer, or re-writing the effect as something else (a behavior?) - unless that is an easy rewrite. Because the effect already has been written, and this dynamic attachment is only desired in one place.
MY FALLBACK DESIGN:
If there is no simple solution, I'll make two versions of the View that needs the effect: one with it and one without it. Have the binding control which of those is visible - I already have the InverseBooleanConverter that is involved in that solution. Which looks like this:
<Label ... IsVisible="{Binding EnableEffect}">
<View.Effects>
<effects:MyGlowEffect Radius="10" Color="White"/>
</View.Effects>
</Label>
<Label ... IsVisible="{Binding EnableEffect, Converter={StaticResource InverseBooleanConverter}}"/>
UPDATE:
Since this is my own custom effect, this should be solvable by adding a custom parameter, and binding that to the boolean in ViewModel as in Docs: Passing Effect Parameters as Attached Properties. (AFAIK, must use "attached" property, in order to use a Binding - effect properties don't appear to respond to dynamic changes.)
However, if there is some "generic" way to do this, for example to enable/disable an effect that I don't have source to, I would prefer that as a solution.
Your were totally right about triggers, you can modify the existing like in my sample, or just add a new one like i guess you wanted:
<Label ...>
<View.Effects>
<effects:MyGlowEffect Radius="10" Color="White" />
</View.Effects>
<Label.Triggers>
<DataTrigger Binding="{Binding EnableEffect TargetType="Label" Value="true">
<Setter Property="effects:MyGlowEffect.Radius" Value="11" />
<Setter Property="effects:MyGlowEffect.Color" Value="Red" />
</DataTrigger>
</Label.Triggers>
</Label>
Related
I'm using a MasterDetailPage in my Xamarin.Forms application.
To creat the menu items, I use buttons
<MasterDetailPage.Master>
<ContentPage Title="Menu">
<StackLayout Orientation="Vertical">
<Button Text="Club-House" Command="{Binding ClubHouseCommand}" />
<Button Text="Parcours" />
<BoxView VerticalOptions="CenterAndExpand" />
<Button Text="A propos" Command="{Binding AProposCommand}" VerticalOptions="End" />
</StackLayout>
</ContentPage>
</MasterDetailPage.Master>
Is there a better way to do it ? I was thinking about something more menuish like MenuItem or else.
Thanks
There is nothing standard for implementing a menu in the Master page.
You can use
ListView
StackLayout
Grid
Or a combination. StackLayout and ListView will most likely be your best options. Personally I go for a StackLayout because it's quicker to code and render than a ListView, which may come with more issues than advantages. However if I have a large menu (which I try to avoid), ListView may be quicker to code. But ListViews are generally meant for dynamically loaded data, not static.
As for the elements, the most common will be
Button
Label
While buttons are designed for clicking, sometimes I move to label's if I don't want to have to undo all the default styling, and use the TapGestureRecognizer.
You can create a new User Control for a menu item, to avoid code replication.
All up, there is no standard. Make it easy to code and understand, and quick to render. How you do that, depends on your requirements.
I am a complete noob to xamarin :)
So was wondering if someone could point me to right resources.
To be short, I want to implement something like this in prism using Xamarin MasterDetailPage.
Using the master detail sample here, the hamburger menu doesn't act as a fly out.
<MasterDetailPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms"
prism:ViewModelLocator.AutowireViewModel="True"
x:Class="HelloWorld.Views.MyMasterDetail">
<MasterDetailPage.Master>
<ContentPage Title="Default">
<StackLayout>
<Button Text="ViewA" Command="{Binding NavigateCommand}" CommandParameter="MyNavigationPage/ViewA?id=A" />
<Button Text="ViewB" Command="{Binding NavigateCommand}" CommandParameter="MyNavigationPage/ViewB?id=B" />
<Button Text="ViewC" Command="{Binding NavigateCommand}" CommandParameter="MyNavigationPage/ViewC?id=C" />
</StackLayout>
</ContentPage>
</MasterDetailPage.Master>
</MasterDetailPage>
Right now, though there is enough space, it shows something like
(just as a sample, I am not using SplitViewMenu at all)
I need icons/some small text to show initially and on clicking hamburger, it should expand (you know just like the first link/ groove music app behavior).
Tips?
Right now, though there is enough space, it shows something like
In my experience, if you have assigned the Symbol property for SimpleNavMenuItem, the possible reason is you haven't imported the Themes file Generic.xaml under Themes folder
This file includes templates, styles for custom controls. For example, for NavMenuItem's template, FontIcon's Glyph property needs to be assigned correctly here:
<DataTemplate x:Key="NavMenuItemTemplate">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="48" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<FontIcon FontSize="16" Glyph="{Binding Path=SymbolAsChar}" VerticalAlignment="Center"
HorizontalAlignment="Center" ToolTipService.ToolTip="{Binding Path=Label}" />
<TextBlock Grid.Column="1" Text="{Binding Path=Label}" VerticalAlignment="Center" />
</Grid>
</DataTemplate>
While SimpleNavMenuItem class's SymbolAsChar property is based on Symbol's value:
public sealed class SimpleNavMenuItem : INavigationMenuItem
{
......
public Symbol Symbol { get; set; }
public char SymbolAsChar => (char) Symbol;
......
}
And if you still can make it work, please share a demo:)
I've sort of been looking for something like this myself since I can't hide the NavigationBar shown in the Master page of the MasterDetailPage when i run it on a Windows 10 Mobile device (I can hide for PC though). So basically, I'm looking into eventually building my own version of the MasterDetailPage.
Since I have not built it yet, I can't tell you exactly how to achieve what you're asking, but I do know that it will require you to either:
Write your own custom renderer for MasterDetailView or,
Write a new control and its renderer
In both cases, your renderer will involve creating and manipulating a new SplitView (which is the native UWP control that your SplitViewMenu example is extending). There's a tutorial for creating the actual UWP control here. If you havent learned about Xamarin's renderers yet, they are the "Translator" and "Interpreter" between a Xamarin.Forms control and a given platform's native control. I suspect Xamarin will eventually rewrite their MastDetailPage renderer for UWP to use a SplitView as a base, but who knows when that will be. Xamarin also has an open source SDK for Xamarin.Forms (as well as the others) on GitHub so you can study the MasterDetailPageRenderer for UWP.
I have a custom control that currently conditionally renders content:
<me:CustomControl>
<switch>
<if "expression is true">
<textbox id="Name" />
</if>
<if "expression is true">
...
</if>
<else>
<textbox id="Name" />
</else>
</switch>
</me:CustomControl>
My example above makes no logical sense, but gets straight to the point. The <if> tag is evaluated by overriding the GetChildControlType function. The <textbox> inside is evaluated in the <if>'s control builder.
What I want to do is completely remove the control from the collection, or even better yet, prevent child controls of <if> from being added to the collection to begin with. If I try to remove them OnInit, I still get the error "The ID 'Name' is already used by another control."
I can't evaluate them in the:
Public Overrides Function GetChildControlType(ByVal tagName... ) As Type
Because I need to perform logic on all the if's and else's within it.
Maybe there's a better way?
Update
I get a compilation error even if I break this thing down to bare bones if there are more than one controls with the same ID, even though overriding CreateChildControls. not sure if I can get around this at all.
Just starting a new project with MVVM light after a few years hiatus. I am wiring up my first VM using the ViewModelLocator and I see that for each new view model we need to create a new property. I am just wondering how to avoid this as the app may end up having quite a few view models (50+). I have gotten it to work using a value converter but then I loose intellisence in the XAML editor.
Any examples from those who may have a solution to this is appreciated.
Note - here is a solution using a value converter, so I can then just pass the parameter into some IoC and get the VM, but then I loose intellisense (WelcomeTitle gets the squiggle).
<Window x:Class="My.MainWindow"
DataContext="{Binding Source={StaticResource Locator},
Converter={StaticResource Locator}, ConverterParameter='foo'}">
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Skins/MainSkin.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Grid x:Name="LayoutRoot">
<TextBlock FontSize="36"
FontWeight="Bold"
Foreground="Purple"
Text="{Binding WelcomeTitle}"
VerticalAlignment="Center"
HorizontalAlignment="Center"
TextWrapping="Wrap" />
</Grid>
</Window>
Update:
Here is another approach, better than using a converter, but still suffers from WelcomeTitle squiggle because the XAML editor does not know the type. I wonder if this effects "blendability"? (I do not have blend handy.)
http://maartendewilde.blogspot.com/2011/01/auto-viewmodel-binding-with-ninject.html
Thanks
For the intellisense, you can try yet more boilerplate on the resources?
/// <summary>
/// Class to contain things
/// </summary>
/// <typeparam name="T">UserID</typeparam>
/// <typeparam name="TK">UserName</typeparam>
public class MyDictionary<T,TK> : Dictionary<T,TK>
or what about using a shared resource dictionary to make intellisense happy?
Dependency injection is a good way to reduce redundant locator code. It involves a generic way of registering service or model providers. From the MSDN.
If you have to create a new property for each view model, it may indicate a weakness in your actual model. When working with VMs I usually find that they are reductive, in that the model contains all pertinent data, and view models get constructed as a subset of properties important to that view.
It is not uncommon for a large project to have 50+ view models.
Is it possible to do data binding on the fields of an object just like in WPF?
Something like this:
<TextBlock Text="{Binding ElementName=lbColor}" />
just for an asp:TextBox element. What I want is that on submit to have the new values inside the binded object and I don't want to manually read and set the values.
if you are binding in a template you can use:
<asp:textbox Text="<%#Bind("lbColor")%>" runat="server" />
see: http://support.microsoft.com/kb/307860
For those looking, I made this javascript plugin. It does data binding very close to what WPF does and is easy to use. It has attached documentation in a .txt file
https://github.com/jdemeuse1204/ObjectDataBinding
Here is an example of what one of my bindings looks like
<input runat="server" style="width: 50px;" data-bind="path: Quote" />
To activate you call
$("#yourelementname").observe(yourobject, 'yourbindingname');
To get the object back for saving or other operations
var obj= $("#yourelementname").getObserveObject('yourbindingname');