【问题标题】:Custom control does not update background color Xamarin Forms自定义控件不更新背景颜色 Xamarin Forms
【发布时间】:2020-06-04 20:07:18
【问题描述】:

我创建了一个自定义控件,我想在单击后更改颜色。我可以成功加载它,但是一旦我运行我的函数并想要更改颜色,什么也没有发生。当我尝试使用常规元素(按钮、标签)时,它可以工作。

自定义控件(即内部带有简单标签的 Grid):

public partial class CustomGrid : Grid
{
    public static readonly BindableProperty ItemProperty = BindableProperty.Create(nameof(Item), typeof(Item), typeof(CustomGrid), propertyChanged: ItemChanged);
    public static readonly BindableProperty CustomColorProperty = BindableProperty.Create(nameof(IsAnonymousSubColor), typeof(Color), typeof(CustomGrid), propertyChanged: CustomColorChanged);

    public Color CustomColor
    {
        get { return (Color)GetValue(CustomColorProperty); }
        set { SetValue(CustomColorProperty, value); }
    }

    static void CustomColorChanged (object bindable, object oldValue, object newValue)
    {
        var x = bindable as CustomGrid;

        if (x.Item != null)
        {
             x.myLabelInMyXaml.BackgroundColor = x.CustomColor;
        }
    }

    static void ItemChanged (object bindable, object oldValue, object newValue)
    {
        var x = bindable as CustomGrid;
    }

    public Item Item
    {
        get { return (Item) GetValue(ItemProperty); }
        set { SetValue(ItemProperty, value); }
    }

    public CustomGrid()
    {
        InitializeComponent();
    }
}

这是我的 xaml,在这里我将它绑定到 viewmodel 颜色代码(绑定在其他元素上效果很好,即使我在同一个 stacklayout 中尝试它)。

                <StackLayout BackgroundColor="Transparent"
                             Padding="0,10,0,0"
                                 VerticalOptions = "StartAndExpand" 
                                BindableLayout.ItemsSource="{Binding newsService.FeedList}">
                    <BindableLayout.ItemTemplate>
                        <DataTemplate>
                            <StackLayout>

                                <controls:CustomGrid Item ="{Binding .}"
                                               CustomColor = "{Binding BindingContext.CustomColorViewModel, Source={x:Reference ParentView}}" />

                            </StackLayout>
                        </DataTemplate>
                    </BindableLayout.ItemTemplate>
                </StackLayout>

视图模型:

    private Color _CustomColorViewModel;
    public Color CustomColorViewModel
    {
        get { return _CustomColorViewModel; }
        set
        {
            _CustomColorViewModel = value;
            RaisePropertyChanged("CustomColorViewModel");
        }
    }

我在加载后更改它:

public void ChangeColor ()
{
    CustomColorViewModel = Color.Red;
}

自定义控件的XAML:

  <?xml version="1.0" encoding="UTF-8"?>
  <Grid xmlns="http://xamarin.com/schemas/2014/forms"
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
         xmlns:controls="clr-namespace:Neutral.Controls"
         xmlns:ffimageloading="clr-namespace:FFImageLoading.Forms;assembly=FFImageLoading.Forms"
         xmlns:fftransformations="clr-namespace:FFImageLoading.Transformations;assembly=FFImageLoading.Transformations"
         xmlns:yummy="clr-namespace:Xamarin.Forms.PancakeView;assembly=Xamarin.Forms.PancakeView"
         x:Name="ParentView"
         x:Class="Project.Controls.CustomGrid">


         <Label x:Name = "myLabelInMyXaml" BackgroundColor = "{Binding CustomColorViewModel}"/>


 </Grid>

但是自定义控件背景颜色没有变化。它在我最初加载时有效,但在我尝试更新时无效。请注意,我对其他元素没有问题,只有这个自定义控件。

不知道为什么它不更新颜色。

【问题讨论】:

  • 你能发布 CustomGrid 的 XAML,很可能你必须在 CustomColorChanged 中执行 x.BackgroundColor=newColor 而你不需要 x:Reference Parentview
  • 也更新了 xaml 代码。

标签: c# xamarin xamarin.forms xamarin.android xamarin.ios


【解决方案1】:

我注意到您在stacklayout 中使用了CustomColor 属性,但您在CustomColor 后台代码中添加了IsAnonymousSubColor 属性。

我将您的CustomColor 背景代码更改为以下格式(只需测试更改颜色的功能)。

  [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class CustomGrid : Grid
    {

        public static readonly BindableProperty CustomColorProperty = BindableProperty.Create(nameof(CustomColor), typeof(Color), typeof(CustomGrid), propertyChanged: CustomColorChanged);

        public Color CustomColor
        {
            get { return (Color)GetValue(CustomColorProperty); }
            set { SetValue(CustomColorProperty, value); }
        }

        static void CustomColorChanged(object bindable, object oldValue, object newValue)
        {
            var x = bindable as CustomGrid;
            x.myLabelInMyXaml.BackgroundColor = x.CustomColor;

        }



        public CustomGrid()
        {
            InitializeComponent();
        }
    }

这里正在运行 GIF。

【讨论】:

  • 您是否将此元素添加到堆栈布局列表中?当我将它绑定到 stacklayout itemssource 列表之外的元素时,它似乎可以工作。
  • 我在StackLayout中添加了它,它正常工作。
【解决方案2】:

这就是问题所在:

x.myLabelInMyXaml.BackgroundColor = x.CustomColor;

改成:

x.myLabelInMyXaml.BackgroundColor = (Color) newValue;

【讨论】:

【解决方案3】:

我认为您可能对绑定上下文有疑问。

如果不查看上下文中的所有代码,很难说。

首先,为什么将属性称为视图模型?名称并不重要,但由于属性不是视图模型,因此令人困惑,而且如果没有看到该属性所在的类,很难说出这里发生了什么。

我怀疑问题出在这里:

<controls:CustomGrid Item ="{Binding .}"
                     CustomColor = "{Binding BindingContext.CustomColorViewModel, Source={x:Reference ParentView}}" />

我认为您的 CustomColor 绑定代码应该改为(假设您的父视图确实命名为 ParentView):

CustomColor = "{Binding Source={x:Reference ParentView}, Path=BindingContext.CustomColorViewModel}"

但这同样是基于缺少一些重要的代码/信息,但如果不是解决方案,希望至少能让你朝着正确的方向前进。

【讨论】:

  • 试过这个但没有成功。有趣的是,如果我将元素移到 stacklayout iemssource 列表之外(具有相同的绑定),它就会起作用。
  • 您的 XAML 中是否有一个名为“ParentView”的元素?它可能默认为真正的父视图,因此当您的控件位于堆栈布局之外时,父视图可能会有所不同。尝试使用 将您的内容页面命名为“ParentView”,或者如果在其他地方使用 ParentView,则使用与 ParentView 不同的名称可能会更好。 (这就是为什么我说缺少信息来了解我的解决方案是否有效。我不知道在这种情况下 ParentView 是什么)。如果 ContentPage 被命名为“ParentView”,我确实测试了我的答案是否有效。
  • 如果你也把它放在一个堆栈布局列表中?对我来说,它似乎只有在我把它放在外面时才有效。我正在使用的页面是一个 contentview 页面,我在那里有 ParentView。
猜你喜欢
  • 2014-09-04
  • 1970-01-01
  • 1970-01-01
  • 2019-06-20
  • 1970-01-01
  • 2021-03-19
  • 2019-09-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多