Home > Back-end >  How to dynamically change the icon on a button based value in a list?
How to dynamically change the icon on a button based value in a list?

Time:10-22

I have the following xaml code:

                <ListView.ItemTemplate>
                    <DataTemplate>
                        <ViewCell>
                            <ViewCell.ContextActions>
                                <MenuItem Text="Check In"
                                      Clicked="CheckInFile"/>
                                <MenuItem Text="Check Out"
                                      Clicked="CheckOutFile"/>
                                <MenuItem Text="Download"
                                      Clicked="DownloadFile"/>
                                <MenuItem Text="Upload Local Copy"
                                      Clicked="UploadFile"/>
                            </ViewCell.ContextActions>

                            <Grid>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="Auto" />
                                    <ColumnDefinition Width="Auto" />
                                </Grid.ColumnDefinitions>
                                <Grid.RowDefinitions>
                                    <RowDefinition Height="30" />
                                    <RowDefinition Height="30" />
                                </Grid.RowDefinitions>

                                <Label Grid.Column="0" Text="{Binding Path=DriveItem.Name}"
                                   FontSize="Small" />
                                <Label Grid.Column="1""
                                    FontFamily="Segoe MDL2 Assets" 
                                       Text="{Binding PublicationStatus}"
                                     />
                            </Grid>
                        </ViewCell>

                    </DataTemplate>
                </ListView.ItemTemplate>

and the related cs code:

   protected override async void OnAppearing()
    {

        var directoryContents = await App.GraphClient.Sites[siteID].Lists[sharedDocsDriveId]
            .Items
            .Request()
            //.Expand(item => item.DriveItem)
            .Expand("driveItem($select=publication,name,id,description,file,webUrl)")
            .GetAsync();

        SharedDocumentList.ItemsSource = directoryContents.CurrentPage.ToList();
      }

For each item that is returned, it contains info about the file - if it's presently checked out or not. the field is "Level" as you can see below/

directoryContents.CurrentPage[i].DriveItem.Publication
{Microsoft.Graph.PublicationFacet}
    AdditionalData: null
    Level: "checkout"
    ODataType: null
    VersionId: "4.0"

If the value of Level is "checkout" I want to show the locked icon using this: https://docs.microsoft.com/en-us/windows/apps/design/style/segoe-ui-symbol-font but if it's "published" I'd like to use the unlock icon for example.

Is there a simple way to do some sort of IF statement within the XAML to evaluate the value of DriveItem.Publication.Level and then display the appropriate icon? I started to go down the route of exposing a new property in my codebehind called publicationStatus but ... maybe that's overkill. I feel like there's a simpler way I'm not thinking of?

CodePudding user response:

There's a smart way to achieve this through a DataTrigger and a Tag property to avoid using IValueConverter or gaining access to parent DataContext from inside a Style.

Inside a list view or a root element

<ListView.Resources>
    <Style x:Key="PublicationStatus" TargetType="Label">        
        <Setter Property="FontFamily" Value="Segoe MDL2 Assets" />
        <Style.Triggers>
            <DataTrigger Binding={Binding Path=Tag, RelativeSource={RelativeSource Self}}"
                         Value="checkout">
                <Setter Property="Text" Value="Icon for checkout"/>
            </DataTrigger>
           <DataTrigger Binding={Binding Path=Tag, RelativeSource={RelativeSource Self}}"
                        Value="published">
                <Setter Property="Text" Value="Icon for published"/>
           </DataTrigger>
        </Style.Triggers>
    </Style>
</ListView.Resources>

Then in code:

<Label Grid.Column="0" Text="{Binding Path=DriveItem.Name}" FontSize="Small" />
<Label Grid.Column="1" Style="{StaticResource PublicationStatus}" Tag="{Binding PublicationStatus}" />

You may also reuse a style and put it into some ResourceDictionary.

Warning. Not tested.

CodePudding user response:

It looks like that your app is a Xamarin UWP app, not a native UWP app.

You could also try to use a ValueConverter when using binding. What you need to do is create a ValueConverter class and make your own logic for converting different strings to different icons in the ValueConverter. After that, you just need to use the ValueConverter as a parameter in the binding.

Here is a sample code that I've tested in a native UWP app. And it should work in the Xamarin UWP app. You need to replace Textblock with Label.

Code-behind:

 public class IconValueConverter: IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        string OutputValue ;

        string textvalue = value as string;
        if (textvalue.Equals("checkout"))
        {
            OutputValue = "\uE701";
        }
        else if (textvalue.Equals("published"))
        {
            OutputValue = "\uE702";
        }
        else 
        {
            OutputValue = "\uE703";
        }


        return OutputValue;
    }

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

MainPage:

 public string IconValue { get; set;}

    public MainPage()
    {
        this.InitializeComponent();

        IconValue = "checkout";

        this.DataContext = this;
    }

Xaml code:

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

<Grid>
    <TextBlock x:Name="MyTextBlcok" Text="{Binding IconValue,Converter={StaticResource IconValueConverter}}" FontFamily="Segoe MDL2 Assets" />
</Grid>
  • Related