Xamarin Forms MVVM在CollectionView中单击一行时显示图标/图像

拉兹万·埃米尔(Razvan Emil)

我希望能够在单击该行时显示(理想情况下是动画)该行中的图像/图标,并且在做出选择之后,导航到另一页,同时将选定的行数据ID传递到下一页。

在此处输入图片说明

我尝试根据不使用mvvm的示例使用Setter属性CustomImageSource,尚未使其正常工作,请帮助(我知道下面的代码是错误的)。

风景:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml">


    <ContentPage.Resources>       
        <Style TargetType="Grid">
            <Setter Property="VisualStateManager.VisualStateGroups">
                <VisualStateGroupList>
                    <VisualStateGroup x:Name="CommonStates">
                        <VisualState x:Name="Normal" />
                        <VisualState x:Name="Selected">
                            <VisualState.Setters>

                                <Setter Property="BackgroundColor"
                                        Value="White" />

                                <Setter Property="CustomImageSource"
                                        Value="select.png" />
                               
                            </VisualState.Setters>
                        </VisualState>
                    </VisualStateGroup>
                </VisualStateGroupList>
            </Setter>
        </Style>
        
        <ResourceDictionary>
            <DataTemplate x:Key="MyCustomCellTemplate">
                <Grid>
                    <customControls:CustomFrame Padding="20" 
                                                Margin="20,10,20,10" 
                                                HeightRequest="50" 
                                                BackgroundColor="{StaticResource frameBackground}" 
                                                BorderColor="Transparent"
                                                CornerRadius="5"
                                                HasShadow="True">
                        <Grid>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="100*" />
                            </Grid.RowDefinitions>

                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="20*" />
                                <ColumnDefinition Width="70*" />
                                <ColumnDefinition Width="10*" />
                            </Grid.ColumnDefinitions>

                            <Image Grid.Row="0"
                                   Grid.Column="0"
                                   Grid.ColumnSpan="1"
                                   Source="site_icon">
                            </Image>


                            <Label Grid.Row="0"
                                   Grid.Column="1"
                                   HorizontalOptions="Start"
                                   VerticalOptions="Center"
                                   FontSize="Small"
                                   FontAttributes="Bold"
                                   Text="{Binding Name}">
                            </Label>


                            <Image x:Name="SelectedIcon"
                                   Grid.Row="0"
                                   Grid.Column="2"
                                   Grid.ColumnSpan="1"
                                   HorizontalOptions="Center"
                                   Source="select.png">
                            </Image>

                        </Grid>

                    </customControls:CustomFrame>
                </Grid>
            </DataTemplate>
        </ResourceDictionary>
    </ContentPage.Resources>
    
    
    <customControls:GradientColorStack StartColor="{StaticResource gradientStartColor}"
                                       EndColor="{StaticResource gradientEndColor}">

        <Grid Margin="0" ColumnSpacing="0" RowSpacing="0" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand">

            <Grid.RowDefinitions>
                <RowDefinition Height="8*"/>
                <RowDefinition Height="4*"/>
                <RowDefinition Height="3*"/>
                <RowDefinition Height="80*"/>
            </Grid.RowDefinitions>

            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="20*" />
                <ColumnDefinition Width="80*" />
            </Grid.ColumnDefinitions>

            <Label Grid.Row="1"
                   Grid.ColumnSpan="2"
                   Text="Select Site"
                   FontSize="Medium"
                   TextColor="White"
                   VerticalOptions="Center"
                   HorizontalOptions="Center">
            </Label>

            <BoxView Grid.Row="3"
                     Grid.ColumnSpan="2"
                     Grid.RowSpan="4"
                     BackgroundColor="{StaticResource mainPageBackground}">
            </BoxView>

            <CollectionView
                            Grid.Row="4"
                            Grid.ColumnSpan="2"
                            EmptyView="No sites for the current user."
                            ItemsSource="{Binding ItemsCollection}"
                            ItemTemplate="{StaticResource MyCustomCellTemplate}"
                            SelectionMode="Single">
            </CollectionView>

        </Grid>
        
    </customControls:GradientColorStack>
    
</ContentPage>

视图模型:

public class MyViewModelClass : BindableBase
    {
        private Page _currentPage;

        private IPageService _pageService;

        private List<CollectionItem> _source;

        public UserSitesVM(Page currentPage,                       
                           IPageService pageService)
        {
            _currentPage = currentPage;
            _pageService = pageService;
        }

        public override async Task InitializeAsync()
        {      
            await PopulateCollection();
        }

        private async Task PopulateCollection()
        {          
            // code to populate collection
            _source = await.........................
            ItemsCollection = new ObservableCollection<CollectionItem>(_source);
            
        }

        public ObservableCollection<CollectionItem> _itemsCollection
        public ObservableCollection<Site> ItemsCollection
        {
            get
            {
                return _itemsCollection;
            }
            set
            {
                _itemsCollection = value;
                RaisePropertyChanged();
            }
        }
        
         private string _customImageSource;
        public string CustomImageSource
        {
            get
            {
                return _customImageSource;
            }
            set
            {
                _customImageSource = value;
                RaisePropertyChanged();
            }

        }

        public static readonly BindableProperty CustomImageSourceProperty = BindableProperty.Create(nameof(CustomImageSource),
            typeof(string), typeof(Grid), defaultValue: string.Empty,
            propertyChanged: (SelectedIconSource, oldValue, newValue) =>
            {
                SelectedIconSource = ImageSource.FromFile((string)newValue);
            });
    }
路Lu-MSFT

您想获得以下结果吗?

在此处输入图片说明

如果是这样,我注意到您使用了MVVM,并且在显示图像时想添加动画。

您可以在ViewModel中添加性能。我添加Isfavourite属性。

   public class MyModel: INotifyPropertyChanged
    {
        string name;
        public string Name
        {
            set
            {
                if (name != value)
                {
                    name = value;
                    OnPropertyChanged("Name");

                }
            }
            get
            {
                return name;
            }
        }
        bool _isfavourite = false;
        public bool Isfavourite
        {
            get
            {
                return _isfavourite;
            }

            set
            {
                if (_isfavourite != value)
                {
                    _isfavourite = value;
                    OnPropertyChanged("Isfavourite");

                }
            }

        }

       
        string _value;
        public string Value
        {
            set
            {
                if (_value != value)
                {
                    _value = value;
                    OnPropertyChanged("Value");

                }
            }
            get
            {
                return _value;
            }
        }


        private Color _textColor=Color.Green;

        public Color TextColor
        {
            get { return _textColor; }
            set
            {
                _textColor = value;

                OnPropertyChanged("TextColor");

            }
        }

     
        public event PropertyChangedEventHandler PropertyChanged;

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

然后,您想在单击该行时显示带有动画的图像。首先,我们应该创建一个自定义图像。当值为true时,我添加BindableProperty称为Animate,显示图像并设置动画。

   public class CustomImage:Image
    {
        public static readonly BindableProperty AnimateProperty =
           BindableProperty.Create(nameof(Animate), typeof(bool), typeof(ImageButton), true, propertyChanged: OnEventNameChanged);

        private static void OnEventNameChanged(BindableObject bindable, object oldValue, object newValue)
        {
            if (newValue is bool)
            {
                bool x = (bool)newValue;
                if (x == true)
                {
                    CustomImage customImage= bindable as CustomImage;
                    // you can add whatever animate here
                    customImage.FadeTo(1, 400);
                   // customImage.TranslateTo(-100, 0, 1000);
                }
           }
        }

        public bool Animate
        {
            get => (bool)GetValue(AnimateProperty);
            set => SetValue(AnimateProperty, value);
        }
        public CustomImage()
        {
           
        }
    }
}

然后使用此customImage到CollectionView(绑定相同的Isfavourite perperty Animate="{Binding Isfavourite}" IsVisible="{Binding Isfavourite}")。注:我并不怎么是你成就你的customView,所以我将其删除,并添加SelectionChangedCommandSelectionChangedCommandParameterCollectionView

    <ContentPage.Resources>
        <Style TargetType="Grid">
            <Setter Property="VisualStateManager.VisualStateGroups">
                <VisualStateGroupList>
                    <VisualStateGroup x:Name="CommonStates">
                        <VisualState x:Name="Normal" />
                        <VisualState x:Name="Selected">
                            <VisualState.Setters>

                                <Setter Property="BackgroundColor"
                                        Value="White" />

                                <!--<Setter Property="CustomImageSource"
                                        Value="select.png" />-->

                            </VisualState.Setters>
                        </VisualState>
                    </VisualStateGroup>
                </VisualStateGroupList>
            </Setter>
        </Style>

        <ResourceDictionary>
            <DataTemplate x:Key="MyCustomCellTemplate">
                <Grid>
                    <customControls:CustomFrame Padding="20" 
                                                Margin="20,10,20,10" 
                                                HeightRequest="50" 
                                                BackgroundColor="Gray" 
                                                BorderColor="Transparent"
                                                CornerRadius="5"
                                                HasShadow="True">
                        <Grid>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="100*" />
                            </Grid.RowDefinitions>

                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="20*" />
                                <ColumnDefinition Width="70*" />
                                <ColumnDefinition Width="10*" />
                            </Grid.ColumnDefinitions>

                            <Image Grid.Row="0"
                                   Grid.Column="0"
                                   Grid.ColumnSpan="1"
                                   Source="site_icon">
                            </Image>


                            <Label Grid.Row="0"
                                   Grid.Column="1"
                                   HorizontalOptions="Start"
                                   VerticalOptions="Center"
                                   FontSize="Small"
                                   FontAttributes="Bold"
                                   Text="{Binding Name}">
                            </Label>


                            <customControls:CustomImage x:Name="SelectedIcon"
                                   Grid.Row="0"
                                   Grid.Column="2"
                                   Grid.ColumnSpan="1"
                                   HorizontalOptions="Center"
                                    Animate="{Binding Isfavourite}"
                                   IsVisible="{Binding Isfavourite}"
                                   Source="select.png" >
                                
                            </customControls:CustomImage>
                           

                        </Grid>

                    </customControls:CustomFrame>
                </Grid>
            </DataTemplate>
        </ResourceDictionary>
    </ContentPage.Resources>


    <!--<customControls:GradientColorStack StartColor="{StaticResource gradientStartColor}"
                                       EndColor="{StaticResource gradientEndColor}">-->

        <Grid Margin="0" ColumnSpacing="0" RowSpacing="0" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand">

            <Grid.RowDefinitions>
                <RowDefinition Height="2*"/>
                <RowDefinition Height="1*"/>
                <RowDefinition Height="1*"/>
                <RowDefinition Height="1*"/>
                <RowDefinition Height="6*"/>
            </Grid.RowDefinitions>

            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="20*" />
                <ColumnDefinition Width="80*" />
            </Grid.ColumnDefinitions>

            <Label Grid.Row="1"
                   Grid.ColumnSpan="2"
                   Text="Select Site"
                   FontSize="Medium"
                   TextColor="Black"
                   VerticalOptions="Center"
                   HorizontalOptions="Center">
            </Label>

           <BoxView Grid.Row="3"
                     Grid.ColumnSpan="2"
                     Grid.RowSpan="4"
                     BackgroundColor="WhiteSmoke">
            </BoxView>
            <CollectionView
                x:Name="MyCollectionView"
                            Grid.Row="4"
                            Grid.ColumnSpan="2"
                            EmptyView="No sites for the current user."
                            ItemsSource="{Binding Stats}"
                            ItemTemplate="{StaticResource MyCustomCellTemplate}"
                            SelectionChangedCommand="{Binding ColorChangeCommand}"
                            SelectionChangedCommandParameter="{Binding SelectedItem, Source={x:Reference MyCollectionView}}"
                            SelectionMode="Single">
            </CollectionView>

        </Grid>

    <!--</customControls:GradientColorStack>-->

</ContentPage>

这是布局背景代码。

    public MainPage()
        {
            InitializeComponent();

            this.BindingContext = new MyViewModel(Navigation);
       
        }

这是我的ViewModel。ColorChangeCommand单击collectionview中的项目时执行将设置Isfavourite为true,显示图片。然后等待0.5秒,然后导航到显示详细信息的page1。

  public class MyViewModel
    {
       
        public ObservableCollection<MyModel> Stats { get; set; }

        public ICommand ColorChangeCommand { protected set; get; }
        public MyViewModel(INavigation navigation)
        {

            
            Stats = new ObservableCollection<MyModel>();
            Stats.Add(new MyModel() { Name="test1",  Value="1" });
            Stats.Add(new MyModel() { Name = "test2", Value = "2" });
            Stats.Add(new MyModel() { Name = "test3", Value = "3" });



                 ColorChangeCommand = new Command<MyModel>(async (key) =>
                 {


                     key.Isfavourite = !key.Isfavourite;
                     await Task.Delay(500);
                     await  navigation.PushModalAsync(new Page1(key));
                 });

        }
    }

这是Page1的背景代码。

 [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class Page1 : ContentPage
    {
        public Page1(MyModel myModel)
        {
           
            InitializeComponent();
            MyLabel.Text = myModel.Name;
        }
    }

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章