首页 > 解决方案 > 如何在后面的代码中更改框架的背景颜色?

问题描述

我正在使用 xamarin 为 android、iOS 和 WP 创建一个应用程序。在我的一个页面中,我有一个frame内部 adatatemplate并且我无法在后面的代码中访问框架元素,所以我将框架的背景颜色绑定到一个变量。当用户点击一个按钮时,颜色应该会改变,但不会。

XAML:

<CollectionView x:Name="collectionView">
   <CollectionView.EmptyView>
      <Label Text="Não foram encontrados contactos com email" x:Name="SemContactos" IsVisible="False"  AbsoluteLayout.LayoutBounds="0.5,0.5,100,100" AbsoluteLayout.LayoutFlags="PositionProportional"/>
   </CollectionView.EmptyView>
   <CollectionView.ItemsLayout>
      <GridItemsLayout Orientation="Vertical" Span="2"/>
   </CollectionView.ItemsLayout>
   <CollectionView.ItemTemplate>
      <DataTemplate x:Name="template">
         <Grid Padding="5" x:Name="grid">
            <Grid.RowDefinitions>
               <RowDefinition Height="50"/>
               <RowDefinition Height="25"/>
               <RowDefinition Height="25"/>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
               <ColumnDefinition Width="70"/>
               <ColumnDefinition Width="70"/>
            </Grid.ColumnDefinitions>
            <Frame BackgroundColor="{DynamicResource myResourceKey}"
               OutlineColor="LightGray"
               CornerRadius="3" Padding="0.5" Grid.RowSpan="3" Grid.ColumnSpan="5" x:Name="frameContacto">
            <Frame.GestureRecognizers>
               <TapGestureRecognizer Tapped="ContactoSelecionado" />
            </Frame.GestureRecognizers>
            <StackLayout  Spacing="5">
               <Image  x:Name="imageX" Grid.RowSpan="2" Grid.ColumnSpan="2" 
                  Source="{Binding Foto}"
                  Aspect="AspectFill"
                  HeightRequest="60"
                  WidthRequest="60"
                  HorizontalOptions="Center" />
               <!--Source="{local:ImageResource KiaiDay.Images.user.png}"-->
               <Label Grid.Row="2" Grid.ColumnSpan="2" Text="{Binding Nome}" FontAttributes="Bold" HorizontalOptions="Center" VerticalOptions="EndAndExpand" TextColor="Black"/>
               <Label Grid.Row="3" Grid.ColumnSpan="2" Text="{Binding Email}" HorizontalOptions="Center" VerticalOptions="StartAndExpand"/>
            </StackLayout>
            </Frame>
         </Grid>
      </DataTemplate>
   </CollectionView.ItemTemplate>
</CollectionView>
<StackLayout AbsoluteLayout.LayoutBounds=".5,1,.5,.1" AbsoluteLayout.LayoutFlags="All" x:Name="butoes" IsVisible="False">
   <StackLayout Orientation="Horizontal" HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand">
      <Button Text="Seleccionar todos" WidthRequest="170" TextColor="White" BackgroundColor="#1E90FF" FontAttributes="Bold" CornerRadius="2" HeightRequest="40" HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand" Clicked="SeleccionarTodos" x:Name="selTodos"/>
      <Button Text="Convidar" WidthRequest="170" TextColor="White" BackgroundColor="#1E90FF" FontAttributes="Bold" CornerRadius="2" HeightRequest="40" HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand"/>
   </StackLayout>
</StackLayout>

和 C#

[XamlCompilation(XamlCompilationOptions.Compile)]

public partial class ConviteEmailPage: ContentPage {

    Color corFrame = Color.White;

    public ConviteEmailPage() {
        this.Resources.Add("myResourceKey", corFrame);
        InitializeComponent();
    }

    private void SeleccionarTodos(object sender, EventArgs e) {
        if (selTodos.Text == "Desmarcar") selTodos.Text = "Seleccionar Todos";
        else selTodos.Text = "Desmarcar";
        corFrame = Color.LightGray;

    }

标签: c#xamarin.forms

解决方案


从代码来看,Frame的颜色在CollectionView.ItemTemplate。如果想在Item中改变颜色,你应该改变模型的数据,而不是直接通过绑定的资源名称或x:名称来改变。

在模型中将MyColor属性添加到模型Monkey

private string mycolor = "Accent";

public string MyColor
{
   get
   {
      return mycolor;
   }
   set
   {
      if (mycolor != value)
      {
          mycolor = value;
          OnPropertyChanged("MyColor");
      }
    }
 }

如果要动态变化,还需要INotifyPropertyChanged建模:

public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
    if (PropertyChanged != null)
    {
        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

MyColor然后在Xaml中绑定:

<ContentPage.Resources>
    <ResourceDictionary>
        <CollectionViewDemos:StringToColorConverter x:Key="StringToColorConverter"/>
    </ResourceDictionary>
</ContentPage.Resources>

Frame BackgroundColor="{Binding MyColor, Converter={StaticResource StringToColorConverter}}"

它还需要IValueConverter从字符串转换颜色:

public class StringToColorConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        //throw new NotImplementedException();
        string valueAsString = value.ToString();
        switch (valueAsString)
        {
            case ("Red"):
                {
                    return Color.Red;
                }
            case ("Accent"):
                {
                    return Color.Accent;
                }
            default:
                {
                    return Color.FromHex(value.ToString());
                }
        }
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

最后,您可以在 CollectionView 时进行测试SelectedItem

<CollectionView ItemsSource="{Binding Monkeys}"
                SelectionMode="Single"
                SelectedItem="{Binding SelectedMonkey, Mode=TwoWay}">

添加selectedMonkeyMonkeyList模型。选中后,将颜色更改为红色,如下所示:

Monkey selectedMonkey;
public Monkey SelectedMonkey
{
    get
    {
        return selectedMonkey;
    }
    set
    {
        if (selectedMonkey != value)
        {
            selectedMonkey.MyTextColor = "Red"; //Here is changing the color
            selectedMonkey = value;
        }
    }
}

推荐阅读