【问题标题】:XAML Change Frame Background Based on BindingXAML基于绑定改变框架背景
【发布时间】:2016-09-07 16:30:20
【问题描述】:

我有一个基于以下类的 ObservableCollection:

public class Data
{
    public string Text { get; set; }
    public DateTime Date { get; set; }
    public bool IsActive { get; set; }
}

这个 observablecollection 被使用和绑定为 ListView 的 ItemSource。下面是展示数据的DataTemplate——

<DataTemplate>
    <ViewCell>
        <Frame OutlineColor="White" HasShadow="False">
             <!-- Data -->
        </Frame>
    </ViewCell>
</DataTemplate>

由于 ObservableCollection 是具有 布尔属性的 Data 类的集合,我想使用它来更改框架的背景颜色

  • 如果 IsActive 属性为真 - BackgroundColor 为红色

  • 如果 IsActive 属性为 false - BackgroundColor 为蓝色

我已经研究了触发器的实现,但是我似乎无法让它们正常工作,而且我不确定我缺少什么。

根据 Xamarin 文档,我应该能够做到:

<Frame>
    <Frame.Trigger>
        <!-- -->
    </Frame.Trigger>  
</Frame>

然而这似乎是不可能的。这也不是——

<Frame>
<Frame.Style>
    <Style TargetType="Frame">
        <Setter Property="BackgroundColor" Value="Blue" />
        <Style.Triggers>
            <DataTrigger Binding="{Binding IsActive}" Value="True">
                <Setter Property="BackgroundColor" Value="Red"/>
            </DataTrigger>
        </Style.Triggers>
    </Style>
</Frame.Style>
</Frame>

上面的代码给出了以下错误信息:

Xamarin.Forms.Xaml.XamlParseException: Position 28:26. The Property TargetType is required to create a Xamarin.Forms.DataTrigger object.

【问题讨论】:

  • 您确定行号与定义框架样式的位置匹配吗?我不确定 xamarin,但可能尝试使用 {x:Type } 扩展而不是依赖于字符串 - > TargetType 属性中的类型转换?
  • 您是否直接在&lt;Frame&gt; 标签中设置您的BackgroundColor?如果是这样,该属性将覆盖任何触发或样式化的值。另一件要尝试的事情可能是使用TargetType={x:Type Frame},偶尔我会看到文本字符串无法解析为实际类型,所以这可以防止这种情况发生。

标签: c# xaml mvvm


【解决方案1】:

不确定您的触发问题,但我认为您应该能够通过首先在 Data 类上实现 INotifyPropertyChanged 来完成颜色更改,如下所示:

public class Data : INotifyPropertyChanged
{
    public string Text { get; set; }
    public DateTime Date { get; set; }

    private bool _isActive;
    public bool IsActive 
    {
        get { return _isActive; }
        set
        {
            if (value == _isActive)
            {
                return;
            }

            _isActive = value;

            NotifyPropertyChanged("IsActive");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public void NotifyPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

然后,在您的 xaml 中,您应该能够执行以下操作:

<DataTemplate>
    <ViewCell>
        <Frame Background="{Binding IsActive, Converter={StaticResource IsActiveToColorConverter}}" OutlineColor="White" HasShadow="False">
             <!-- Data -->
        </Frame>
    </ViewCell>
</DataTemplate>

IsActiveToColorConverter 看起来像这样:

public class IsActiveToColorConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var isActive = (bool) value;

        return isActive ? "Red" : "Blue";
    }

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

【讨论】:

  • OP 没有提到布尔属性会实时改变。所以 NotifyProperty 不是必需的。但是对于这种情况,Converter 是一个不错的选择。所以+1。
猜你喜欢
  • 1970-01-01
  • 2019-01-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-16
  • 1970-01-01
相关资源
最近更新 更多