locked
Dynamically set styles RRS feed

  • Question

  • Hi

    I'm constructing a menu that is loaded dynamically using an MVVM approach. My problem is that I would like to set one of the items as 'selected' and consequently for it to use a different style to the others. I've tried using the code below but although the items are created fine the styles read from the Model are not applied. Does anyone know if it's possible to bind to the Style attribute and, if not, what the alternative is? Thanks

    <ItemsControl ItemsSource="{Binding MenuItems}">
    <ItemsControl.ItemTemplate>
    <DataTemplate>
    <HyperlinkButton Content="{Binding Path=Title}" Style="{Binding Path=StyleName}"/>
    </DataTemplate>
    </Items.Control.ItemTemplate>
    </ItemsControl>


     

    Wednesday, July 28, 2010 11:26 AM

Answers

  • Hi

    check the below links

    http://forums.silverlight.net/forums/t/104058.aspx

    http://forums.silverlight.net/forums/t/24634.aspx

    Maybe this class will be helpful for u

    public static class ThemeResources
        {
            /// <summary>      
            /// Purpose:      
            /// </summary>
            public static void ApplyTheme(string theme)
            {
                if (string.IsNullOrEmpty(theme))
                    return;

                var obj = XamlReader.Load(theme);

                ResourceDictionary rec = (ResourceDictionary)obj;

                using (StringReader stream = new StringReader(theme))
                {
                    using (XmlReader reader = XmlReader.Create(stream))
                    {
                        //Application.Current.Resources.Clear();
                        while (reader.Read())
                        {
                            if (reader.NodeType == XmlNodeType.Element)
                            {
                                if (reader.Name == "Style")
                                {
                                    string styleKey = reader.GetAttribute("x:Key");
                                    if (!string.IsNullOrEmpty(styleKey))
                                    {
                                        Style applicationStyle = new Style();
                                        applicationStyle = (Style)((ResourceDictionary)obj)[styleKey];

                                        Application.Current.Resources.Remove(styleKey);
                                        Application.Current.Resources.Add(styleKey, applicationStyle);
                                    }
                                    else
                                    {
                                        styleKey = reader.GetAttribute("x:Name");
                                        if (!string.IsNullOrEmpty(styleKey))
                                        {
                                            Style applicationStyle = new Style();
                                            applicationStyle = (Style)((ResourceDictionary)obj)[styleKey];

                                            Application.Current.Resources.Remove(styleKey);
                                            Application.Current.Resources.Add(styleKey, applicationStyle);
                                        }
                                    }

                                }
                            }
                        }
                    }
                }
            }
        }

    Thursday, July 29, 2010 8:57 AM

All replies

  • It should be possible to bind the Style attribute as you suggest. 

    Maybe the binding value is not coming through as expected  - what is the type of StyleName in the binding on the Style property in your code? I think it should work if the property is of type System.Windows.Style...


    HTH


    Wednesday, July 28, 2010 3:30 PM
  • Thanks - you're right my StyleName property had been exposed as a string not as a System.Windows.Style. The problem then becomes howver that I'm not sure how I reference the specific styles that are defined in the page, eg in the viewmodel I have something along the lines of

    Before

    menuItem.StyleName="Style1";

    After

    menuItem.StyleName=new Style() -- how do I tell it that I want to use a specific style, Style1?

    Thanks again.

    Thursday, July 29, 2010 4:31 AM
  • Hi

    I'm not sure I understand your latest issue - can you post some sample code and I can have a look?


    Thanks

    Thursday, July 29, 2010 8:51 AM
  • Hi

    check the below links

    http://forums.silverlight.net/forums/t/104058.aspx

    http://forums.silverlight.net/forums/t/24634.aspx

    Maybe this class will be helpful for u

    public static class ThemeResources
        {
            /// <summary>      
            /// Purpose:      
            /// </summary>
            public static void ApplyTheme(string theme)
            {
                if (string.IsNullOrEmpty(theme))
                    return;

                var obj = XamlReader.Load(theme);

                ResourceDictionary rec = (ResourceDictionary)obj;

                using (StringReader stream = new StringReader(theme))
                {
                    using (XmlReader reader = XmlReader.Create(stream))
                    {
                        //Application.Current.Resources.Clear();
                        while (reader.Read())
                        {
                            if (reader.NodeType == XmlNodeType.Element)
                            {
                                if (reader.Name == "Style")
                                {
                                    string styleKey = reader.GetAttribute("x:Key");
                                    if (!string.IsNullOrEmpty(styleKey))
                                    {
                                        Style applicationStyle = new Style();
                                        applicationStyle = (Style)((ResourceDictionary)obj)[styleKey];

                                        Application.Current.Resources.Remove(styleKey);
                                        Application.Current.Resources.Add(styleKey, applicationStyle);
                                    }
                                    else
                                    {
                                        styleKey = reader.GetAttribute("x:Name");
                                        if (!string.IsNullOrEmpty(styleKey))
                                        {
                                            Style applicationStyle = new Style();
                                            applicationStyle = (Style)((ResourceDictionary)obj)[styleKey];

                                            Application.Current.Resources.Remove(styleKey);
                                            Application.Current.Resources.Add(styleKey, applicationStyle);
                                        }
                                    }

                                }
                            }
                        }
                    }
                }
            }
        }

    Thursday, July 29, 2010 8:57 AM
  • Thanks again - certainly of interest. All in all I think that my design might need reworking - to try and make things simple I was hoping to be able to apply a style via the WCF data bind but on reflection I think that the style should be applied within the view itself in some way. Guess I'll find a better way...

    Thursday, July 29, 2010 12:25 PM