Mahapps - Changing the Style of a Tile with Binding in a class property - MVVM

Asked

Viewed 85 times

1

I’m creating a dynamic menu using Tiles (Mahapps). I have two types of Tiles that I can use: Largetilestyle and Smalltilestyle. For this, I have a function that allows me to pass the name of Style via parameter and set the property Style, when the Tile was created.

Creation of Tiles:

this.Tile.Add(
   new TileItem() 
   { 
       Icon = new PackIconFontAwesome() 
       { 
         Kind = PackIconFontAwesomeKind.Angellist 
       }, 
       Text = "Usuários", 
       Style = "LargeTileStyle", 
       Background = "Green", 
       NavigationDestination = new Uri("Views/UsuarioList.xaml", UriKind.RelativeOrAbsolute) 
    }
);

this.Tile.Add(
    new TileItem() 
    { 
        Icon = new PackIconFontAwesome() 
        { 
           Kind = PackIconFontAwesomeKind.Apple 
        }, 
        Text = "Clientes", 
        Style = "SmallTileStyle", 
        Background = "Blue", 
        NavigationDestination = new Uri("Views/ClienteList.xaml", UriKind.RelativeOrAbsolute) 
    }
);

Class TileItem:

internal class TileItem : BindableBase
    {
        private object _icon;
        private string _text;
        private string _style;
        private string _background;
        private DelegateCommand _command;
        private Uri _navigationDestination;


        public object Icon
        {
            get { return this._icon; }
            set { this.SetProperty(ref this._icon, value); }
        }

        public string Text
        {
            get { return this._text; }
            set { this.SetProperty(ref this._text, value); }
        }

        public string Style
        {
            get { return this._style; }
            set { this.SetProperty(ref this._style, value); }
        }

        public string Background
        {
            get { return this._background; }
            set { this.SetProperty(ref this._background, value); }
        }

        public ICommand Command
        {
            get { return this._command; }
            set { this.SetProperty(ref this._command, (DelegateCommand)value); }
        }

        public Uri NavigationDestination
        {
            get { return this._navigationDestination; }
            set { this.SetProperty(ref this._navigationDestination, value); }
        }

        public bool IsNavigation => this._navigationDestination != null;
    }

The problem is that in the block below, when I do one Binding to set the property Style, does not work because he can not set the names I pass by parameter. Someone knows how to help me?

Style:

<ResourceDictionary>          

            <Style x:Key="LargeTileStyle" TargetType="Controls:Tile">
                <Setter Property="Width" Value="300" />
                <Setter Property="Height" Value="125" />
                <Setter Property="TitleFontSize" Value="16" />
            </Style>

            <Style x:Key="SmallTileStyle" TargetType="Controls:Tile">
                <Setter Property="Width" Value="147" />
                <Setter Property="Height" Value="125" />
                <Setter Property="TitleFontSize" Value="16" />
            </Style>
        </ResourceDictionary> 

Layout of my Window:

<Grid>
        <ListBox ItemsSource="{Binding Tile}" ScrollViewer.HorizontalScrollBarVisibility="Disabled">
            <ListBox.ItemsPanel>
                <ItemsPanelTemplate>
                    <WrapPanel IsItemsHost="True"/>
                </ItemsPanelTemplate>                    
            </ListBox.ItemsPanel>
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <controls:Tile
                        Title="{Binding Text}"
                        controls:ControlsHelper.MouseOverBorderBrush="{DynamicResource BlackBrush}"
                        Command="{Binding DataContext.TileClickCommand, RelativeSource={RelativeSource AncestorType=ListBox}}"
                        CommandParameter="{Binding}"
                        HorizontalTitleAlignment="Left"
                        Background="{Binding Background}"
                        Style="{Binding Style}"
                        TiltFactor="2">
                        <Image  Width="60"
                            Height="60"/>
                        <!--<Source="{Binding OmsConnectionTypeId, Converter={StaticResource ConnectionTypeToIconConverter}}"/>-->
                    </controls:Tile>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>       
    </Grid>

1 answer

0


To access a style or some resource specific to your application, you can search for it by name using the method FindResource(). To use this method, its class must belong to FrameworkElement, such as, for example, the code Behind (.Cs) window.

Style smallTileStyle = (Style)FindResource("SmallTileStyle"); 
Style largeTileStyle = (Style)FindResource("LargeTileStyle");

Change your class Change your class TileItem and change the property type Style for the guy Style:

internal class TileItem : BindableBase
{
    private object _icon;
    private string _text;
    private Style _style;
    private string _background;
    private DelegateCommand _command;
    private Uri _navigationDestination;


    public object Icon
    {
        get { return this._icon; }
        set { this.SetProperty(ref this._icon, value); }
    }

    public string Text
    {
        get { return this._text; }
        set { this.SetProperty(ref this._text, value); }
    }

    public Style Style
    {
        get { return this._style; }
        set { this.SetProperty(ref this._style, value); }
    }

    public string Background
    {
        get { return this._background; }
        set { this.SetProperty(ref this._background, value); }
    }

    public ICommand Command
    {
        get { return this._command; }
        set { this.SetProperty(ref this._command, (DelegateCommand)value); }
    }

    public Uri NavigationDestination
    {
        get { return this._navigationDestination; }
        set { this.SetProperty(ref this._navigationDestination, value); }
    }

    public bool IsNavigation => this._navigationDestination != null;
}

nomeDoSeuObjeto.Style = smallTileStyle;

At the time of creating your Tiles, use the previously informed code to fetch the desired Tiles and assign them to your Tileitem object:

// Busca o style nos Resources (App.xaml)
Style smallTileStyle = (Style)FindResource("SmallTileStyle"); 
Style largeTileStyle = (Style)FindResource("LargeTileStyle");

// Atribui o style nos tiles criados
this.Tile.Add(
   new TileItem() 
   { 
       Icon = new PackIconFontAwesome() 
       { 
         Kind = PackIconFontAwesomeKind.Angellist 
       }, 
       Text = "Usuários", 
       Style = largeTileStyle, 
       Background = "Green", 
       NavigationDestination = new Uri("Views/UsuarioList.xaml", UriKind.RelativeOrAbsolute) 
    }
);

this.Tile.Add(
    new TileItem() 
    { 
        Icon = new PackIconFontAwesome() 
        { 
           Kind = PackIconFontAwesomeKind.Apple 
        }, 
        Text = "Clientes", 
        Style = smallTileStyle, 
        Background = "Blue", 
        NavigationDestination = new Uri("Views/ClienteList.xaml", UriKind.RelativeOrAbsolute) 
    }
);

In your XAML bind to the created property:

<Controls:Tile 
     Title="TileOne" 
     Style="{Binding Style}" 
     Margin="133,539,666,21" Width="Auto" Height="Auto" />
  • Thanks for helping Perozzo, but I didn’t understand the part where you say: "To use this method, your class must belong to Frameworkelement, such as the code Behind (.Cs) of a Window." I don’t know how this works...

  • I tried, put in the Page Load method, but it didn’t work...

  • That would have to stay within some function?

  • What didn’t work? Did it go wrong or just didn’t work? If it didn’t work it’s because of your Binding. As I said in the other answer, the Binding of the Style property can change depending on how you designed your app for Binding. I tested this solution before publishing the answer and it worked perfectly.

  • It was underlined in red the "Findresource"... I didn’t understand why I set my Style Operty with smallTileStyle: nameSeuObject.Style = smallTileStyle; and if I need to set with Largetilestyle?

  • If it was underlined in red it’s because you’re using it in the wrong place. In what class did you put it? If you have placed yourself in the Tileitem class it will not work because as mentioned your class must be a Frameworkelement. About smallTileStyle is just one example, if you want to use largeTileStyle, you assign it instead of the other. When creating your Tileitem object, you place either Smalltilestyle or Largetilestyle in the Style property.

  • In what class do you create the Tiles? Up there you mentioned the "Creation of the Tiles". In what class do you do this?

  • Tileitem class

  • Get in the chat room so we can get this over with.

Show 5 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.