gpt4 book ai didi

c# - 如何在 Xamarin 表单中使用 MVVM 仅为 Collection View 中的选定框架设置颜色?

转载 作者:行者123 更新时间:2023-12-05 00:43:33 26 4
gpt4 key购买 nike

我正在使用 RelativeSource 绑定(bind) 为 Collection View 中的框架绑定(bind) 背景颜色。但是 Collection View 中所有框架的背景颜色都在变化。我需要仅为我选择的框架设置背景颜色

这是我的 xaml 代码

<StackLayout Padding="10">
<CollectionView x:Name="list" ItemsSource="{Binding samplelist}">
<CollectionView.ItemsLayout>
<GridItemsLayout Orientation="Vertical" Span="2" HorizontalItemSpacing="10" VerticalItemSpacing="10" />
</CollectionView.ItemsLayout>
<CollectionView.ItemTemplate>
<DataTemplate>
<StackLayout>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup Name="CommonStates">
<VisualState Name="Selected">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="Green" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Frame CornerRadius="10" HasShadow="False" BackgroundColor="{Binding BackgroundTest,Mode=TwoWay, Converter={StaticResource colorConverter}}" HeightRequest="75" Margin="5,0,0,0" >
<StackLayout Orientation="Vertical">
<StackLayout.GestureRecognizers>
<TapGestureRecognizer Command="{Binding Source={x:Reference test}, Path=BindingContext.TriggerScene}"
CommandParameter="{Binding .}"/>
</StackLayout.GestureRecognizers>

这是我在 Viewmodel

中的代码
public bool FrameColorChange=true;
private Color _backgroundTest;
public Color BackgroundTest
{
get { return _backgroundTest; }
set
{
if (value == _backgroundTest)
return;

_backgroundTest = value;
OnPropertyChanged(nameof(BackgroundTest));
}
}
private async void TriggerScene(Scene scene)
{

if (FrameColorChange==true)
{
BackgroundTest = Color.Gray;
FrameColorChange = false;
}
else
{
BackgroundTest = Color.White;
FrameColorChange = true;
}
}

我已经完成了一些修复,例如

how to access child elements in a collection view?

但没有任何帮助。我也尝试了 SelectionChanged 事件。但是 SelectionChanged 的​​问题是它没有正确触发,因为我的框架中有 TapGestureRecognizer。我希望在我的 TriggerScene 命令 中为所选帧设置颜色绑定(bind)我的 viewmodel 中的 TapGestureRecognizer。我不想在后面使用代码。我不知道如何解决这个问题有什么建议吗?

最佳答案

我已经在另一个答案中发布了解决您问题的一种方法,现在我想提供一个更简单的解决方案(尽管我不会声称它是最好的)。

注意,在这个解决方案中,与我的其他答案相反,您不需要向 Collection View 中的对象添加多余的属性,但新属性直接定义在ViewModel。


解决问题的一种方法是:

  1. 在您的 ViewModel 中定义一个名为 SelectedItem 的属性:这将跟踪当前选定的项目。
  2. 然后你将 FrameBackgroundColor 绑定(bind)到新属性:SelectedItem,为此你需要一个 ValueConverter 接受 SelectedItemConverterParameter:当前 Frame
  3. Frame 内,在 StackLayout 中有 good old TapGestureRecognizer,其处理程序在调用时将设置所选项目
  4. 设置 SelectedItem 时,会调用 OnPropertyChanged 并为 CollectionView 中的每个项目调用 ValueConverter。转换器然后检查 Frame 的 BindingContext(它绑定(bind)到的项目!)是否与 SelectedItem 相同,如果是,则将其颜色设置为 Gray(选中!)

当然,下面我添加了一个完整的最小工作示例。随意复制粘贴并使用它。

Page1.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="App1.Page1"
x:Name="test"
xmlns:local="clr-namespace:App1">

<ContentPage.BindingContext>
<local:ViewModel/>
</ContentPage.BindingContext>

<ContentPage.Resources>
<ResourceDictionary>
<local:SelectedToColorConverter x:Key="selectedToColorConverter"/>
</ResourceDictionary>
</ContentPage.Resources>

<ContentPage.Content>
<StackLayout Padding="10">
<CollectionView ItemsSource="{Binding samplelist}">

<CollectionView.ItemsLayout>
<GridItemsLayout Orientation="Vertical" Span="2" HorizontalItemSpacing="10" VerticalItemSpacing="10" />
</CollectionView.ItemsLayout>

<CollectionView.ItemTemplate>
<DataTemplate>
<StackLayout>

<Frame x:Name="frame" CornerRadius="10"
HasShadow="False"
BackgroundColor="{Binding Source={x:Reference test}, Path=BindingContext.SelectedItem, Converter={x:StaticResource selectedToColorConverter}, ConverterParameter={x:Reference frame}}"
HeightRequest="75"
Margin="5,0,0,0" >
<StackLayout Orientation="Vertical">
<StackLayout.GestureRecognizers>
<TapGestureRecognizer Command="{Binding Source={x:Reference test}, Path=BindingContext.TriggerSceneCommand}" CommandParameter="{Binding .}"/>
</StackLayout.GestureRecognizers>
<Label Text="{Binding Text}"/>
<Label Text="{Binding Description}"/>
</StackLayout>
</Frame>

</StackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</StackLayout>

</ContentPage.Content>
</ContentPage>

ViewModel.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.Runtime.CompilerServices;
using Xamarin.Forms;

namespace App1
{
public class ViewModel : INotifyPropertyChanged
{

public ViewModel()
{
samplelist = new List<item>
{
new item { Text = "Uno", Description = "Uno Description bla bla" },
new item { Text = "Dos", Description = "Dos Description bla bla" },
new item { Text = "Tres", Description = "Tres Description bla bla" }
};

TriggerSceneCommand = new Command<item>(TriggerScene);
}

public List<item> samplelist { get; set; }


private item _selectedItem;
public item SelectedItem
{
get => _selectedItem;
set
{
_selectedItem = value;
OnPropertyChanged();
}
}



public Command TriggerSceneCommand { get; set; }
private void TriggerScene(item newSelectedItem)
{
SelectedItem = newSelectedItem;
}


public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged([CallerMemberName] string name = "")
{
var propertyChanged = PropertyChanged;

propertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}

}

public class item
{

public String Text { get; set; }

public String Description { get; set; }

}


public class SelectedToColorConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{

Color result = Color.White;


if (value != null && parameter != null && ((Frame)parameter).BindingContext != null && (item)value == (item)((Frame)parameter).BindingContext)
{
result = Color.Gray;
}


return result;

}

public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return null;
}
}
}

为什么不,让我们在这里放一个奖金

您可以在 TapGestureRecognizer 的事件处理程序中添加两行代码,以便在一段时间(可能是三秒?)后返回原始颜色。

只需将 ViewModel 中的 TriggerScene 方法更改如下(参见代码注释):

private void TriggerScene(item newSelectedItem)
{
// Highlight selection!
SelectedItem = newSelectedItem;

// Sit and wait...
await Task.Delay(3000);

// Go back to normal!
SelectedItem = null;
}

关于c# - 如何在 Xamarin 表单中使用 MVVM 仅为 Collection View 中的选定框架设置颜色?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69388564/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com