如何从自定义控件中的 CollectionView 绑定 ItemsSource? [英] How to bind an ItemsSource from a CollectionView in a custom control?

查看:30
本文介绍了如何从自定义控件中的 CollectionView 绑定 ItemsSource?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 CollectionView 制作自定义控件.问题是我想从 MainPage 而不是从控件中给它 ItemsSource 并且 ItemsSource 将它与我的 ObservableCollection 所在的 ViewModel 进行通信.这是我的代码:

I am making a custom control with a CollectionView. The problem is that I want to give it the ItemsSource from the MainPage and not from the control and that ItemsSource communicates it with my ViewModel where my ObservableCollection is. This is my code:

FloatingButton.xaml:

FloatingButton.xaml:

<?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="CustomControlWithList.FloatingButton"
             x:Name="FloatingButtonView">


    <StackLayout>

        <AbsoluteLayout>
            <CollectionView
                x:Name="listView"
                Margin="0,0,36,0"
                AbsoluteLayout.LayoutBounds="1,0,AutoSize,AutoSize"
                AbsoluteLayout.LayoutFlags="PositionProportional"
                BackgroundColor="Transparent"
                ItemsSource="{Binding ItemSource}"
                IsVisible="{Binding IsVisible}"
                Rotation="180"
                WidthRequest="60">

                <CollectionView.ItemTemplate>

                    <DataTemplate>

                        <Grid
                            Padding="5"
                            HeightRequest="50"
                            WidthRequest="50">

                            <Grid.RowDefinitions>

                                <RowDefinition Height="Auto" />


                            </Grid.RowDefinitions>

                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="Auto" />


                            </Grid.ColumnDefinitions>
                            <!--This ImageButton contais the data of the list-->
                            <ImageButton
                                Padding="10"
                                BackgroundColor="{Binding ColorButton}"
                                Command="{Binding Source={x:Reference page}, Path=BindingContext.LaunchWeb}"
                                CommandParameter="{Binding Website}"
                                CornerRadius="70"
                                Rotation="180"
                                Source="{Binding Image}" 
                               
                                 />
                        </Grid>


                    </DataTemplate>

                </CollectionView.ItemTemplate>


            </CollectionView>
        </AbsoluteLayout>
        <ImageButton
            Margin="15"
            Padding="10"
            WidthRequest="70"
            HeightRequest="70"
            BackgroundColor="{Binding PrimaryButtonColor}"
            Command="{Binding OpenFloating}"
            CornerRadius="70"
            HorizontalOptions="End"
            Source="{Binding PrimaryImageSource}"
            VerticalOptions="EndAndExpand" />

    </StackLayout>


</ContentView>

FloatingButton.xaml.cs:

FloatingButton.xaml.cs:

 public partial class FloatingButton : ContentView
{


    //===============Item Source=====================
    public static readonly BindableProperty ItemSourceProperty =
            BindableProperty.Create("ItemSource", typeof(CollectionView),typeof(FloatingButton));

    public CollectionView ItemSource
    {
        get { return (CollectionView)GetValue(ItemSourceProperty); }
        set { SetValue(ItemSourceProperty, value); }
    }
    //=================================================Flo


    //===============Primary Button Image=====================
    public static readonly BindableProperty PrimaryImageSourceProperty =
            BindableProperty.Create("PrimaryImageSource", typeof(ImageSource), typeof(FloatingButton));

    public ImageSource PrimaryImageSource
    {
        get { return (ImageSource)GetValue(PrimaryImageSourceProperty); }
        set { SetValue(PrimaryImageSourceProperty, value); }
    }
    //=============================================================

    //===============Primary Button Color=====================

    public static readonly BindableProperty PrimaryButtonColorProperty =
           BindableProperty.Create("PrimaryButtonColor", typeof(Color), typeof(FloatingButton));

    public Color PrimaryButtonColor
    {
        get { return (Color)GetValue(PrimaryButtonColorProperty); }
        set { SetValue(PrimaryButtonColorProperty, value); }
    }
    //=============================================================

    public FloatingButton()
    {
        InitializeComponent();
        BindingContext = this;

     

    }
}

MainPage.xaml:

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"
             x:Class="CustomControlWithList.MainPage"
             x:Name="page"
             xmlns:local="clr-namespace:CustomControlWithList">

    <local:FloatingButton
        ItemSource="ItemList"
        PrimaryImageSource="dots.png"
        PrimaryButtonColor="Green"        
        
        />

</ContentPage>

MainPage.xaml.cs:

MainPage.xaml.cs:

 public partial class MainPage : ContentPage
{
    public MainPage()
    {
        InitializeComponent();
        BindingContext = new ViewModel();
    }
}

ViewModel.cs:

ViewModel.cs:

public class ViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(string propertyName = "")
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }


    public ObservableCollection<Items> ItemList { get; set; }

    private bool isVisible;

    public bool IsVisible
    {
        get => isVisible;
        set
        {
            isVisible = value;
            OnPropertyChanged();
        }
    }


    public ViewModel()
    {

        ItemList = new ObservableCollection<Items>();

        ItemList.Add(new Items { Website = "https://facebook.com", Image = "facebook.png", ColorButton = "#B52D50" });
        ItemList.Add(new Items { Website = "https://twitter.com", Image = "twitter.png", ColorButton = "#B52D50" });
        ItemList.Add(new Items { Website = "https://www.instagram.com", Image = "insta.png", ColorButton = "#B52D50" });

    }
}

Items.cs:

 public class Items : INotifyPropertyChanged
{

    string url, image, color;

    public string Website
    {
        get { return url; }
        set
        {
            url = value;
            OnPropertyChanged("url");

        }
    }
    public string Image
    {
        get
        {
            return image;
        }

        set
        {
            image = value;
            OnPropertyChanged("image");
        }
    }

    public string ColorButton
    {
        get
        {
            return color;
        }

        set
        {
            color = value;
            OnPropertyChanged("color");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(string propertyName = "")
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

推荐答案

您可以将 ItemSource 设置为可绑定属性,而不是整个 CollectionView .

You could set the ItemSource as bindable property instead of the whole CollectionView .

顺便说一句,既然你用过自定义视图,那么你需要直接在xaml中设置绑定路径.行 BindingContext = this; 将打破 CustomView 和 ContentPage 之间的绑定.

By the way , since you had used Custom View , you need to set the binding path in xaml directly . The line BindingContext = this; will break the binding between CustomView and ContentPage .

所以你可以像下面这样修改代码

So you could modify the code like following

<?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="CustomControlWithList.FloatingButton"
             x:Name="FloatingButtonView">


    <StackLayout>

        <AbsoluteLayout>
            <CollectionView
                x:Name="listView"
                Margin="0,0,36,0"
                AbsoluteLayout.LayoutBounds="1,0,AutoSize,AutoSize"
                AbsoluteLayout.LayoutFlags="PositionProportional"
                BackgroundColor="Transparent"
                ItemsSource="{Binding Source={x:Reference FloatingButtonView}, Path=ItemSource}"
                IsVisible="{{Binding Source={x:Reference FloatingButtonView}, Path=CollectionViewVisible}"
                Rotation="180"
                WidthRequest="60">

                <CollectionView.ItemTemplate>

                    <DataTemplate>

                        <Grid
                            Padding="5"
                            HeightRequest="50"
                            WidthRequest="50">

                            <Grid.RowDefinitions>

                                <RowDefinition Height="Auto" />


                            </Grid.RowDefinitions>

                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="Auto" />


                            </Grid.ColumnDefinitions>
                            <!--This ImageButton contais the data of the list-->
                            <ImageButton
                                Padding="10"
                                BackgroundColor="{Binding ColorButton}"
                                Command="{{Binding Source={x:Reference FloatingButtonView}, Path=LaunchWeb}"
                                CommandParameter="{{Binding Source={x:Reference FloatingButtonView}, Path=Website}"
                                CornerRadius="70"
                                Rotation="180"
                                Source="{Binding Image}" 
                               
                                 />
                        </Grid>


                    </DataTemplate>

                </CollectionView.ItemTemplate>


            </CollectionView>
        </AbsoluteLayout>
        <ImageButton
            Margin="15"
            Padding="10"
            WidthRequest="70"
            HeightRequest="70"
            BackgroundColor="{{Binding Source={x:Reference FloatingButtonView}, Path=PrimaryButtonColor}"
            Command="{Binding Source={x:Reference FloatingButtonView}, Path=OpenFloating}"
            CornerRadius="70"
            HorizontalOptions="End"
            Source="{{Binding Source={x:Reference FloatingButtonView}, Path=PrimaryImageSource}"
            VerticalOptions="EndAndExpand" />

    </StackLayout>


</ContentView>

public FloatingButton()
{
   InitializeComponent();
   //   BindingContext = this;

}

//...

//===============Item Source=====================
        public static readonly BindableProperty ItemSourceProperty =
                BindableProperty.Create("ItemSource", typeof(ObservableCollection<Items>), typeof(FloatingButton));

        public ObservableCollection<Items> ItemSource
        {
            get { return (ObservableCollection<>)GetValue(ItemSourceProperty); }
            set { SetValue(ItemSourceProperty, value); }
        }


        public static readonly BindableProperty CollectionViewVisibleProperty =
                BindableProperty.Create("PrimaryImageSource", typeof(bool), typeof(FloatingButton),false);

        public bool CollectionViewVisible
        {
            get { return (bool)GetValue(CollectionViewVisibleProperty); }
            set { SetValue(CollectionViewVisibleProperty, value); }
        }

public static readonly BindableProperty LaunchWebProperty =
            BindableProperty.Create(nameof(LaunchWeb), typeof(ICommand), typeof(FloatingButton));

        public ICommand LaunchWeb
        {
            get => (ICommand)GetValue(LaunchWebProperty );
            set => SetValue(LaunchWebProperty , value);
        }

        public static BindableProperty WebsiteProperty =
            BindableProperty.Create(nameof(Website), typeof(object), typeof(FloatingButton));

        public object Website
        {
            get => (object)GetValue(WebsiteProperty );
            set => SetValue(WebsiteProperty , value);
        }

     //other bindable property like this

在内容页面

现在你可以像下面这样设置绑定

in ContentPage

Now you can set the binding like following

 <local:FloatingButton
        ItemSource="{Binging ItemList}"
        CollectionViewVisible = "{Binding IsVisible}"
        PrimaryImageSource="dots.png"
        PrimaryButtonColor="Green"        
        
        />

这篇关于如何从自定义控件中的 CollectionView 绑定 ItemsSource?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆