I have a custom behavior to validate telephonenumbers in my view attached to a entry:
<Entry x:Name="phoneNumber" Text="{Binding TelephoneNum, Mode=TwoWay}">
<Entry.Behaviors>
<behaviors:TelNumBehavior x:Name="NumValidatorUser" />
</Entry.Behaviors>
</Entry>
I am using the mvvm pattern with view and viewmodel.
The behavior has a bindable isValid property. How can I use that value in my Viewmodel? How can these two classes communicate? The messaging-service is not an option for me, because I have multiple behaviors and I need to validate them all. Is there a way to access the isValid-att of the behaviors?
Name your page, to be referenced later on:
<ContentPage x:Name="Root" etc, etc>
in your behavior set the path and source to the page's binding-context:
<Entry x:Name="phoneNumber" Text="{Binding TelephoneNum, Mode=TwoWay}">
<Entry.Behaviors>
<behaviors:TelNumBehavior x:Name="NumValidatorUser" />
IsValid="{Binding Source={x:Reference Root},
Path=BindingContext.YourPropertyIsValid, Mode=TwoWay}"/>
</Entry.Behaviors>
</Entry>
Related
I have some code that looks like this:
<Frame CornerRadius="20" >
<Frame.Content>
<Grid x:Name="detailRowArea" HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand">
<xaml:CardWordsFourRowsPlus IsVisible="{Binding FourRowsPlus}" />
<xaml:CardWordsFourRows IsVisible="{Binding FourRows}" />
<xaml:CardWordsThreeRows IsVisible="{Binding ThreeRows}" />
<xaml:CardWordsTwoRows IsVisible="{Binding TwoRows}" />
</Grid>
</Frame.Content>
</Frame>
I just now noticed that the developer had used Frame.Content
Can anyone tell me why this is used? The code seems to work without it so I am wondering what advantage it offers.
There really isn't any advantage other than I guess readability, but the Content tags really aren't needed. The Forms control in xaml will assume that any content that appears between the start and end tags is assumed to be assigned to the Content property.
If you want a more detailed explanation you can check out the Content Properties section in the docs.
If you want to not use the <Frame.Content> tag that is fine, bear in mind that Frame descends from ContentView thus you would ideally define the content of this view in the Content tag. This is more of a semantic decision as opposed to performative decision.
This being said, you would need to use the content tag if you wanted to implement any kind of OnPlatform code in your frame. For example (hand coded, could be wrong)
<Frame>
<Frame.CornerRadius>
<OnPlatform x:TypeArguments="x:Single">
<On Platform="iOS">50</On>
<On Platform="Android">75</On>
</OnPlatform>
</Frame.CornerRadius>
<Frame.Content>
<Label Text="Hello World"/>
</Frame.Content>
</Frame>
I have XAML code that looks like this;
<?xml version="1.0" encoding="UTF-8"?>
<ContentPage
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:Japanese;assembly=Japanese"
x:Class="Japanese.GettingStarted"
x:Name="gettingStarted"
Title="Getting Started">
<ContentPage.Content>
My C#
using System;
using System.Collections.Generic;
using Xamarin.Forms;
namespace Japanese
{
public partial class GettingStarted : ContentPage
{
public GettingStarted()
{
The code works fine but I would like to know if there is any advantage or if it is normal to specify x:Name in the XAML?
Yes, there are reasons. But if you haven't found them yet, you probably don't need it right now.
The most obvious reason is if you need to refer to it from your XAML. For example, you are working with data-binding and use a ListView. On the ListView, you use a simple TextCell which has context actions. The XAML could look like this (taken from here and tweaked a bit):
<ListView ItemsSource="{Binding YourItems}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.ContextActions>
<MenuItem Command="{Binding DeleteCommand}" CommandParameter="{Binding .}" Text="Delete" IsDestructive="True" />
</ViewCell.ContextActions>
<StackLayout Padding="15,0">
<Label Text="{Binding title}" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Now, if you have worked with data-binding before, you will know that the bindings of the MenuItems in there are bound to each instance of the object that is in the YourItems collection.
But, it doesn't make sense to implement a delete command on an instance in that collection. You would want that on your view model. To do this, you will have to give your page a name, and refer to the command like this: <MenuItem Command="{Binding Source={x:Reference MyPage}, Path=BindingContext.DeleteCommand}" CommandParameter="{Binding .}" Text="Delete" IsDestructive="True" /> where MyPage would be the value you put in the x:Name attribute.
Other examples are probably out there, but this is a prominent one. If you do not have to refer to the page in any way, giving it a name add no real value.
My code has:
<Button x:Name="correctButton" HeightRequest="60" HorizontalOptions="FillAndExpand" VerticalOptions="StartAndExpand">
<Button.FontSize>
<OnPlatform x:TypeArguments="x:Double" iOS="25" Android="20" />
</Button.FontSize>
</Button>
Can someone explain what x:Double means
I have broken it down for you with comments in the XAML.
<!-- Here is the button declared, note how you also see the x:Name here -->
<Button x:Name="correctButton" HeightRequest="60" HorizontalOptions="FillAndExpand" VerticalOptions="StartAndExpand">
<!-- Besides giving properties to a control, in this case a button, as attributes, you can also set them by adding them as child nodes. That is what happens with the FontSize here -->
<Button.FontSize>
<!-- We are not just setting the FontSize here, we are also letting the value be dependent on which platform we are running on. For iOS the value will be 25, for Android 20. -->
<OnPlatform x:TypeArguments="x:Double" iOS="25" Android="20" />
</Button.FontSize>
</Button>
Now, the x:Double is needed to tell the OnPlatform tag which type we should provide to it, this can also be x:Int32 or any other type if needed. Because we will always provide string values in the OnPlatform tag, it needs to know to what type it has to cast the value.
Remember that I pointed out to you also the x:Name property. the x is a shorthand for the namespace where to find the type. If you look at your page declaration, it will probably have an attribute like: xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml", see how the x is declared here? That is why the x is needed in front, to tell the XAML that the Double type can be found in the http://schemas.microsoft.com/winfx/2009/xaml namespace, abbreviated to x by default.
Note that the OnPlatform tag in this way is deprecated as of Xamarin.Forms 2.3.4. You should now use it as such:
<Button x:Name="correctButton" HeightRequest="60" HorizontalOptions="FillAndExpand" VerticalOptions="StartAndExpand">
<Button.FontSize>
<OnPlatform x:TypeArguments="x:Double" x:Key="WindowBackgroundTable">
<On Platform="Android" Value="20" />
<On Platform="iOS" Value="25" />
</OnPlatform>
</Button.FontSize>
</Button>
Sorry for the poor english.
When used in XAML this tag needs the type of the value you're sending to the property, once this is a generic method. I belive that XF uses reflection and castings to set the attribute to the specific platform.
See more in this article.
I hope it helps you.
I need to support validation on some standard AutoSuggestBox control. So my idea was to customize AutoSuggestBox control by changing it's TextBox to ValidatingTextBox (my implementation of ValidatingTextBox by James Croft). Is that even possible? If yes - how, and if not - what is the alternative?
So my idea was to customize AutoSuggestBox control by changing it's TextBox to ValidatingTextBox
It is not recommended replacing the TextBox of AutoSuggestBox. Some default functionalities might fail because of that. Instead, you can add some function to it. And WinRTXamlToolkit offers a great validation extension to TextBox control.
You can apply this extension to AutoSuggestBox by following steps:
Reference WinRTXamlToolkit in your project. Add reference of WinRTXamlToolkit.Controls.Extensions in your XAML page like below:
<Page
...
xmlns:extensions="using:WinRTXamlToolkit.Controls.Extensions"
...>
Create a copy of your AutoSuggestBox control's style template with Visual Studio. Or you can copy the template from here, and apply it to your AutoSuggestBox control.
Find the TextBox Control in the template. Add extensions:FieldValidationExtensions.Format="the format you need" to it like below:
<TextBox extensions:FieldValidationExtensions.Format="Numeric"
x:Name="TextBox" ScrollViewer.BringIntoViewOnFocusChange="False" DesiredCandidateWindowAlignment="BottomEdge" Header="{TemplateBinding Header}" Margin="0" PlaceholderText="{TemplateBinding PlaceholderText}" Style="{TemplateBinding TextBoxStyle}" Width="{TemplateBinding Width}" Canvas.ZIndex="0"/>
If you want to show validation error message. You can change the panel of this TextBox from Grid to StackPanel and add a TextBlock like below:
<StackPanel>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="Orientation">
<VisualState x:Name="Landscape"/>
<VisualState x:Name="Portrait"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<TextBox extensions:FieldValidationExtensions.Format="Numeric"
x:Name="TextBox" ScrollViewer.BringIntoViewOnFocusChange="False" DesiredCandidateWindowAlignment="BottomEdge" Header="{TemplateBinding Header}" Margin="0" PlaceholderText="{TemplateBinding PlaceholderText}" Style="{TemplateBinding TextBoxStyle}" Width="{TemplateBinding Width}" Canvas.ZIndex="0"/>
<TextBlock Text="{Binding (extensions:FieldValidationExtensions.ValidationMessage), ElementName=TextBox}"
Visibility="{Binding (extensions:FieldValidationExtensions.ValidationMessageVisibility), ElementName=TextBox}" />
...
</StackPanel>
Now you get a basic validatingAutoSuggestBox ready for use.
I using the toolkit which provide the MultiSelectionList control in wp7, I am trying to bind the names to the multiselectItem using the property ItemsSource in C#.
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<StackPanel>
<TextBlock Text="Please select the satellites from the list:-" />
<toolkit:MultiselectList Name="multiSelectionList">
<toolkit:MultiselectItem Content="{Binding Name}" />
</toolkit:MultiselectList>
</StackPanel>
</Grid>
But I got this error.
Items collection must be empty before using ItemsSource.
I tested the service in other parts of the app and it is working with no issues.
Please advise me.Thanks,
You're adding an item to the MultiSelectList when you do:
<toolkit:MultiselectItem Content="{Binding Name}" />
By the time you assign the ItemsSource, which I assume you're doing in the code-behind somewhere, there is already an item in the list (the one above). This is why the error is getting thrown. You could manually clear the list before setting the source, but that's not necessarily considered good practice. What you could do instead is create a DataTemplate, not an actual instance of a MultiSelectItem. I'm not familiar with this control, but try:
<toolkit:MultiselectList Name="multiSelectionList">
<toolkit:MultiSelectList.ItemTemplate>
<DataTemplate>
<toolkit:MultiselectItem Content="{Binding Name}" />
</DataTemplate>
</toolkit:MultiSelectList.ItemTemplate>
</toolkit:MultiselectList>