简体   繁体   English

如何从自定义控件中的 CollectionView 绑定 ItemsSource?

[英]How to bind an ItemsSource from a CollectionView in a custom control?

I am making a custom control with a CollectionView.我正在使用 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.问题是我想从 MainPage 而不是从控件中给它 ItemsSource 并且 ItemsSource 将它与我的 ObservableCollection 所在的 ViewModel 进行通信。 This is my code:这是我的代码:

FloatingButton.xaml:浮动按钮.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:主页.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:视图模型.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:项目.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));
    }
}

You could set the ItemSource as bindable property instead of the whole CollectionView .您可以将 ItemSource 设置为可绑定属性而不是整个CollectionView

By the way , since you had used Custom View , you need to set the binding path in xaml directly .顺便说一下,由于您使用过自定义视图,因此您需要直接在 xaml 中设置绑定路径。 The line BindingContext = this;BindingContext = this; will break the binding between CustomView and ContentPage .将打破 CustomView 和 ContentPage 之间的绑定。

So you could modify the code like following所以你可以像下面这样修改代码

in 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 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"        
        
        />

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM