Xamarin表单自定义控件绑定问题

时间:2019-06-18 20:43:16

标签: xamarin xamarin.forms

我有一个自定义控件,提供了一个List<string>参数,它为每个字符串绘制一个框作为标签。

这是一个正在运行的版本。点击“添加标签”会为每次点击一次添加一个标签。

我想更改代码,以便将List转换为其他类型的对象,这就是控件显示的内容。

enter image description here

首先,我显示了适用于上图的代码。然后,我显示了无法使用的代码的更改版本。希望对于回答这个问题的任何人,看到有效的前代码和无效的后代码,您都可以轻松地发现问题。

MainPage.xaml

<?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:App7"
             x:Class="App7.MainPage">

    <StackLayout>
        <BoxView HeightRequest="100" />

        <local:CustomControl 
            SideTabs="{Binding MainNavigationTabs}" 
        />

        <Button Text="Add Tab" Command="{Binding AddTab}" />

    </StackLayout>

</ContentPage>

MainPageModel.cs

public class MainPageModel : FreshBasePageModel
{
    public MainPageModel() { }

    public List<string> MainNavigationTabs { get; set; }

    private int _index = 0;

    public Command AddTab
    {
        get
        {
            return new Command(() =>
            {
                _index++;

                var tabs = new List<string>();

                for (var index = 1; index <= _index; index++)
                {
                    tabs.Add($"Tab {index}");
                }

                MainNavigationTabs = tabs;
            });
        }
    }
}

CustomControl.xaml

<ContentView xmlns="http://xamarin.com/schemas/2014/forms" 
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 x:Class="App7.CustomControl"
                 BackgroundColor="Beige"
                 x:Name="this">
    <ContentView.Content>
        <StackLayout>
            <StackLayout Orientation="Vertical"
                             BindableLayout.ItemsSource="{Binding Source={x:Reference this}, Path=SideTabs}">

                <BindableLayout.ItemTemplate>
                    <DataTemplate>
                        <ContentView WidthRequest="237"
                                         Margin="0"
                                         BackgroundColor="Blue"
                                         Padding="10">
                            <Label Text="{Binding .}" TextColor="White" />
                        </ContentView>
                    </DataTemplate>
                </BindableLayout.ItemTemplate>
            </StackLayout>
        </StackLayout>
    </ContentView.Content>
</ContentView>

CustomControl.xaml.cs

[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class CustomControl : ContentView
{
    public CustomControl()
    {
        InitializeComponent();
    }

    public static readonly BindableProperty SideTabsProperty = BindableProperty.Create(
                                       propertyName: "SideTabs",
                                       returnType: typeof(List<string>),
                                       declaringType: typeof(CustomControl),
                                       defaultBindingMode: BindingMode.OneWay,
                                       defaultValue: new List<string>());

    public List<string> SideTabs
    {
        get { return base.GetValue(SideTabsProperty) as List<string>; }
        set { base.SetValue(SideTabsProperty, value); }
    }
}

我更改了CustomControl,将List<string>转换为List<SideTab>对象,并将控件绑定到该对象。这是代码...

CustomControl.xaml.cs

[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class CustomControl : ContentView
{
    public CustomControl()
    {
        InitializeComponent();
    }

    public static readonly BindableProperty SideTabsProperty = BindableProperty.Create(
                                       propertyName: "SideTabs",
                                       returnType: typeof(List<string>),
                                       declaringType: typeof(CustomControl),
                                       defaultBindingMode: BindingMode.OneWay,
                                       defaultValue: new List<string>());

    public List<string> SideTabs
    {
        get
        {
            var tabs = new List<string>();

            foreach (var tab in _SideTabs)
            {
                tabs.Add(tab.Text);
            }

            return tabs;
        }
        set
        {
            var tabs = new List<SideTab>();

            foreach (var tab in value)
            {
                tabs.Add(new SideTab() { Text = tab });
            }

            _SideTabs = tabs;
        }
    }

    public List<SideTab> _SideTabs
    {
        get { return base.GetValue(SideTabsProperty) as List<SideTab>; }
        set { base.SetValue(SideTabsProperty, value); }
    }
}

public class SideTab
{
    public string Text { get; set; }
}

CustomControl.xaml

<ContentView xmlns="http://xamarin.com/schemas/2014/forms" 
                    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                    x:Class="App7.CustomControl"
                    BackgroundColor="Beige"
                    x:Name="this">
    <ContentView.Content>
        <StackLayout>
            <StackLayout Orientation="Vertical"
                                BindableLayout.ItemsSource="{Binding Source={x:Reference this}, Path=_SideTabs}">

                <BindableLayout.ItemTemplate>
                    <DataTemplate>
                        <ContentView WidthRequest="237"
                                            Margin="0"
                                            BackgroundColor="Blue"
                                            Padding="10">
                            <Label Text="{Binding Text}" TextColor="White" />
                        </ContentView>
                    </DataTemplate>
                </BindableLayout.ItemTemplate>
            </StackLayout>
        </StackLayout>
    </ContentView.Content>
</ContentView>

注意增加了_SideTabs属性。设置SideTabs后,它将List<string>转换为List<SideTab>

我该如何进行这项工作?这是上述代码更改的结果...

enter image description here

1 个答案:

答案 0 :(得分:1)

尝试这样

 public static readonly BindableProperty TabsListProperty = BindableProperty.Create(nameof(TabsList), typeof(List<TabItem>), typeof(ScrollableTabs), null, propertyChanged: (bindable, oldValue, newValue) =>
    {
        ((ScrollableTabs)bindable).InitializeTabs();
    });

    private void InitializeTabs()
    {
        //Write your logic here
    }


    public List<TabItem> TabsList
    {
        get
        {
            return (List<TabItem>)GetValue(TabsListProperty);
        }
        set
        {
            SetValue(TabsListProperty, value);

        }
    }