【问题标题】:How to bind an ItemsSource from a CollectionView in a custom control?如何在自定义控件中从 CollectionView 绑定 ItemsSource?
【发布时间】:2020-10-14 21:22:43
【问题描述】:

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

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:

 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:

<?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();
    }
}

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));
    }
}

【问题讨论】:

    标签: c# xamarin.forms


    【解决方案1】:

    您可以将 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"        
            
            />
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-09
      • 1970-01-01
      • 1970-01-01
      • 2021-10-24
      相关资源
      最近更新 更多