Issue
I'm trying to make a custom control that provides some standard layout for dialogs, where there's button on the top right (within a grid) which has a property for the command and can be used like a StackLayout with content passed into it.
However, I want to achieve this by specifying all the layout for the control with xaml (not code). I know you can do simple things with ControlTemplates, but I'm trying add a command.
I've tried this a couple of times and given up.
The issues have been setting the content area, where the control can be used with various controls inside and binding the command which is implementing in xaml (with callong BindableProperty within xaml).
Solution
In your case you could use Bindable Property to pass value from ViewModel to your custom control .
1. Create a CustomControl with bindable property
<?xml version="1.0" encoding="UTF-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="App29.MyCustomControl"
x:Name="CustomView" // set name of view
>
<ContentView.Content>
<StackLayout>
</StackLayout>
</ContentView.Content>
</ContentView>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace App29
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class MyCustomControl : ContentView
{
public MyCustomControl()
{
InitializeComponent();
}
public static readonly BindableProperty ButtonClickCommandProperty =
BindableProperty.Create(nameof(ButtonClickCommand), typeof(ICommand), typeof(MyCustomControl));
public ICommand ButtonClickCommand
{
get => (ICommand)GetValue(ButtonClickCommandProperty);
set => SetValue(ButtonClickCommandProperty, value);
}
public static BindableProperty ButtonClickParameterProperty =
BindableProperty.Create(nameof(ButtonClickParameter), typeof(object), typeof(MyCustomControl));
public object ButtonClickParameter
{
get => (object)GetValue(ButtonClickParameterProperty);
set => SetValue(ButtonClickParameterProperty, value);
}
public static BindableProperty ButtonTitleProperty =
BindableProperty.Create(nameof(ButtonTitle), typeof(object), typeof(MyCustomControl),string.Empty);
public string ButtonTitle
{
get => (string)GetValue(ButtonTitleProperty);
set => SetValue(ButtonTitleProperty, value);
}
public static BindableProperty ChildLayoutProperty =
BindableProperty.Create(nameof(ChildLayout), typeof(View), typeof(MyCustomControl),propertyChanged: OnChildLayoutChanged);
public View ChildLayout
{
get => (View)GetValue(ChildLayoutProperty);
set => SetValue(ChildLayoutProperty, value);
}
static void OnChildLayoutChanged(BindableObject bindable, object oldValue, object newValue)
{
// Property changed implementation goes here
var Custom = bindable as MyCustomControl;
//child is the value that pass from viewmodel
var child = newValue as View;
// do something you want , like add it to stacklayout
var stack = Custom.Content as StackLayout;
stack.Children.Add(child);
}
//...other bindable property
}
}
in ContentPage
Now you can pass value to the custom control from ViewModel or code behind like following
<local:MyCustomControl ButtonClickCommand="{Binding xxx}" ButtonClickParameter="{Binding xxx}" ButtonTitle="{Binding xxx}" >
<local:MyCustomControl.Content>
<Button />
</local:MyCustomControl.Content>
</local:MyCustomControl>
For mode details about Bindable Property you could check https://docs.microsoft.com/en-us/xamarin/xamarin-forms/xaml/bindable-properties
Answered By - Lucas Zhang - MSFT
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.