繁体   English   中英

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

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

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

浮动按钮.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:

 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;

     

    }
}

主页.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:

 public partial class MainPage : ContentPage
{
    public MainPage()
    {
        InitializeComponent();
        BindingContext = new 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" });

    }
}

项目.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

顺便说一下,由于您使用过自定义视图,因此您需要直接在 xaml 中设置绑定路径。 BindingContext = this; 将打破 CustomView 和 ContentPage 之间的绑定。

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

在 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

在内容页面

现在您可以设置如下绑定

 <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