0

In short, I want to make a collection of icons in a GridView from which the user can select one to change their profile icon.

I'm thinking that I can achieve that by declaring the icons I need on a ResourceDictionary

    <ResourceDictionary
          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
          xmlns:iconPacks="using:MahApps.Metro.IconPacks">

    <iconPacks:PackIconMaterial x:Key="IconCarrot" Kind="Carrot"/>

    <FontIcon x:Key="IconRobot" FontFamily="Segoe MDL2 Assets" Glyph="&#xE99A;"/>

    <!--As can we see, the icons are of different types-->

    </ResourceDictionary>

Add that in App.xaml

<Application.Resources ...>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="ResourceDictionaries/MyIcons.xaml"/>
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Application.Resources>

Also, I created a class to instantiate a IconObject with two properties: the actual Icon and a string that I want to use like a tooltip text

public class IconObject
{
    // I really don't know what type I need to use here
    public object DisplayedIcon { get; set; }

    // Tooltip
    public string DisplayedToolTip { get; set; }

    // Contructor
    public IconObject(object theIcon, string theTooltip)
    {
        DisplayedIcon = theIcon;
        DisplayedToolTip = theTooltip;
    }
}

So, in code I have a ObservableCollection<IconObject> that I want to populate

private void PopulateTheObservableCollection()
{
   IconObjects.Add(new IconObject(Application.Current.Resources["IconCarrot"], "Carrot"));
}

Finally, I'm trying to bind on a GridView

<GridView ItemsSource="{x:Bind IconObjects}">
        <GridView.ItemsPanel>
            <ItemsPanelTemplate>
                <ItemsWrapGrid MaximumRowsOrColumns="6" Orientation="Horizontal"  ItemHeight="50" />
            </ItemsPanelTemplate>
        </GridView.ItemsPanel>

        <GridView.ItemTemplate>
            <DataTemplate x:DataType="local:IconObject" >
                <Viewbox Child="{x:Bind DisplayedIcon}" ToolTipService.ToolTip="{x:Bind DisplayedToolTip}"/>
            </DataTemplate>
        </GridView.ItemTemplate>
</GridView>

But throws an error (and I can see why but I don't know ho to fix it).

The questions here are

  1. Is this a good approach to doing this (to have a grid view populated with icons that the user can select and then use the icon selected)?
  2. What type of property do I need to use to store an icon?
  3. Do you have any suggestion?

(Thank you for your time and for reading all this)

Jonas
  • 23
  • 9

1 Answers1

1

What type of property do I need to use to store an icon?

Based on your code, you want to add the icon into Viewbox, the type of Child proeprty is UIElement, so you can set your DisplayedIcon property as UIElement type or keep object type and use Converter method to convert it. In addition, if you want to add the icon into Viewbox, you need to remove it in the ResourceDictionary prior and then add it into Viewbox, an instance of element cannot appear multiple times in XAML tree. For example:

Model:

public class IconObject
{
    // I really don't know what type I need to use here
    public UIElement DisplayedIcon { get; set; }

    // Tooltip
    public string DisplayedToolTip { get; set; }

    // Contructor
    public IconObject(UIElement theIcon, string theTooltip)
    {
        DisplayedIcon = theIcon;
        DisplayedToolTip = theTooltip;
    }
}

.xaml.cs:

Update:

private void PopulateTheObservableCollection()
{
    ResourceDictionary dic = Application.Current.Resources.MergedDictionaries[0];
    UIElement iconElement = dic["IconCarrot"] as UIElement;
    dic.Remove("IconCarrot");
    IconObjects.Add(new IconObject(iconElement, "Carrot"));
}

Is this a good approach to doing this

You can try to use DataTemplateSelector method to create different DataTemplate and Model based on your different types of icon. For more details about DataTemplateSelector, you can refer to this document.

Faywang - MSFT
  • 5,798
  • 1
  • 5
  • 8
  • For some reason still gives me an UnhandledException error. The debugger shows that, in fact, the ObservableCollection have one IconObject inside: DisplayedIcon = {MahApps.Metro.IconPacks.PackIconMaterial} DisplayedToolTip = "Carrot" but it seems that cannot be displayed as a child of the Viewbox. – Jonas Jun 26 '20 at 02:31
  • May I know how you added the icon source? Did you directly the icon sources in App.xaml or add them on a new ResourceDictionary and then Merged the ResourceDictionary into App.Resources? If you added them on a new ResourceDictionary, you need to get the ResourceDictionary object and get the icon source from this ResourceDictionary instead of Application.Current.Resources. – Faywang - MSFT Jun 26 '20 at 08:01
  • Sure, I updated the question (was easier to explain, I think. At least we have a visual representation). Also, I saw [this answer](https://stackoverflow.com/a/1209630/13386674) do you know if that applies to Viewboxes? – Jonas Jun 26 '20 at 08:42
  • 1
    I have updated my answer, you can check the **Update** part. – Faywang - MSFT Jun 26 '20 at 08:56