2

I have a gridview that looks something like this:

<GridView ItemContainerStyle="{StaticResource GridViewItemStyle2}" ItemsSource="{Binding MyMeetingsSquareUsers}" Grid.Row="1" Margin="10,10,10,0"  SelectionMode="None" HorizontalContentAlignment="Left" VerticalContentAlignment="Bottom">
    <GridView.ItemsPanel>
        <ItemsPanelTemplate>
            <ItemsWrapGrid Orientation="Vertical" MaximumRowsOrColumns="1"/>
        </ItemsPanelTemplate>
    </GridView.ItemsPanel>
    <GridView.ItemTemplate>
        <DataTemplate>
            <Grid Height="35" Width="35" Margin="0,0,10,0" >
                <Border BorderBrush="red" BorderThickness="1" CornerRadius="15">
                    <Ellipse>
                        <Ellipse.Fill>
                            <ImageBrush Stretch="Fill" ImageSource="ms-appx:///Images/photo_empty.png"/>
                        </Ellipse.Fill>
                    </Ellipse>
                </Border>
            </Grid>
        </DataTemplate>
    </GridView.ItemTemplate>
</GridView>

The ItemsSource I use is a list of items of this type:

public class MeetingInvitee
{
    public string id { get; set; }
    public string status { get; set; }
    public User user { get; set; }
    public BitmapImage photo { get; set; }
}

What I would like to know is, if it is possible to change the color of the Border I use depending on the value in status

For example if I had 3 possible status: Accepted, Rejected, Pending, the colors would be set to either Green, Red or Yellow accordingly.

so if one of the items on the list had a status of Rejected the border would have a red brush

Thought
  • 5,326
  • 7
  • 33
  • 69
  • If you've got the Interactivity/Interactions namespaces you'd just use a combination of DataTriggerBehavior and VisualStateManager like shown in the answer to [this question](http://stackoverflow.com/questions/7439532/datatrigger-in-winrt) which I considered marking as duplicate. – Chris W. Jul 23 '15 at 20:11

2 Answers2

1

Conditional templates (instead of style data triggers unfortunately) are the way to go in a store app. What you need to do is define three different templates for each color and in the code behind create a template selector.

Data Template Selector

   public class MeetingTemplateSelector : DataTemplateSelector
    {
        public DataTemplate AcceptedTemplate { get; set; }

        public DataTemplate RejectedTemplate { get; set; }

        public DataTemplate PendingTemplate { get; set; }

        protected override DataTemplate SelectTemplateCore(object item, 
                  DependencyObject container)
        {
           DataTemplate result;

           switch( ((MeetingInvitee) item).Status)
           {
                case "Accepted" : result = AcceptedTemplate; break;
                case "Rejected" : result = RejectedTemplate; break;
                case "Pending"  : result = PendingTemplate; break;
           }

          return result;
        }
    }

Declare Templates in the Resources

<UserControl.Resources>
    <DataTemplate x:Key="AcceptedTemplate">
        <Border Background="Green">
             ...
        </Border>
    </DataTemplate>
    <DataTemplate x:Key="RejectedTemplate">
        <Border Background="Red">
             ...
        </Border>
    </DataTemplate>
    <DataTemplate x:Key="PendingTemplate">
        <Border Background="Yellow">
             ...
        </Border>
    </DataTemplate>

    <local:MeetingTemplateSelector x:Key="meetingSelector"
                                    AcceptedTemplate="{StaticResource AcceptedTemplate}"
                                    RejectedTemplate="{StaticResource RejectedTemplate}"
                                    PendingTemplate="{StaticResource PendingTemplate}">
    </local:MeetingTemplateSelector >
</UserControl.Resources>

Usage

<GridView ItemContainerStyle="{StaticResource GridViewItemStyle2}" 
          ItemsSource="{Binding MyMeetingsSquareUsers}" 
          ItemTemplateSelector="{StaticResource meetingSelector}">
ΩmegaMan
  • 29,542
  • 12
  • 100
  • 122
  • @Ric I wish Microsoft would standardize Xaml going forward. I find that that the styling one does on WPF does not work on Silverlight which does not work on Window's store apps. Maybe with universal apps...that will change. – ΩmegaMan Jul 24 '15 at 15:25
1

You can use an implementation of the IValueConverter interface and pass that when you bind the Background property of your Border to your Status property of the viewmodel. Example:

class StatusValueConverter : IValueConverter
{
    private static SolidColorBrush _acceptedBrush = new SolidColorBrush(Colors.Green);
    private static SolidColorBrush _pendingBrush = new SolidColorBrush(Colors.Yellow);
    private static SolidColorBrush _rejectedBrush = new SolidColorBrush(Colors.Red);

    public object Convert(object value, Type targetType, object parameter, string language)
    {
        SolidColorBrush brush = null;

        if (value != null)
        {
            string status = value.ToString();

            switch (status)
            {
                case "Accepted":
                    brush = _acceptedBrush;
                    break;
                case "Pending":
                    brush = _pendingBrush;
                    break;
                case "Rejected":
                    brush = _rejectedBrush;
                    break;
            }
        }

        if (brush == null)
        {
            throw new ArgumentException("Status not valid.");
        }

        return brush;
    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        // You need this if TwoWay binding mode is used.
    }
}

Add the value converter to the page resources (where local is the prefix for the namespace in which I defined the StatusValueConverter):

<Page.Resources>
    <local:StatusValueConverter x:Key="StatusConverter" />
</Page.Resources>

In your xaml define your Border element like this:

<Border BorderBrush="{Binding Status, Converter={StaticResource StatusConverter}}" 
                            BorderThickness="1" CornerRadius="15">
                        <Ellipse>
                            <Ellipse.Fill>
                                ...
                            </Ellipse.Fill>
                        </Ellipse>
                    </Border>

If you want a completely different visual tree for different values in your view model, then use a DataTemplateSelector.

Panayot Todorov
  • 397
  • 2
  • 11