OverflowStack
OverflowStack

Reputation: 909

XAML Change Frame Background Based on Binding

I have an ObservableCollection which is based on the following class:

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

This observablecollection is used and binded as ItemSource for ListView. The following is DataTemplate for displaying data -

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

Since the ObservableCollection is a collection of Data class which has a boolean property, I want to use it in order to change the frame's background color:

I've looked into implementation of Triggers, however I can't seem to get them working correctly, and I'm not sure what I'm missing.

According to Xamarin Documentation I should be able to do :

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

However that doesn't seem to be possible. Neither is this -

<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>

The code above gives the following error message:

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

Upvotes: 5

Views: 2616

Answers (1)

Jake Shanley
Jake Shanley

Reputation: 913

Not sure about your trigger problem but I think you should be able to accomplish the color changing by first implementing INotifyPropertyChanged on your Data class like so:

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));
        }
    }
}

Then, in your xaml, you should be able to do something like this:

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

Where IsActiveToColorConverter looks something like:

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();
    }
}

Upvotes: 5

Related Questions