![](/img/trans.png)
[英]How to bind the ItemsSource property of a nested collectionView to the item of the CollectionView in which is contained?
[英]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 之间的绑定。
所以你可以像下面这样修改代码
<?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.