Home Forums WPF controls Xceed Toolkit Plus for WPF How to create styles based on another Xceed style

Tagged: ,

Viewing 2 posts - 1 through 2 (of 2 total)
  • Author
    Posts
  • aggietech
    Participant
    Post count: 3
    #43703 |

    Hello,
    I am having the following styling issue.
    I’m trying to apply new themes dynamically by removing and loading the resource dictionaries on demand.

                    Theme newTheme = e.NewValue as Theme;
                    dockingManager.Theme = newTheme;
    
                    FrameworkElement parent = FindGlobalContainer(dockingManager); //.dockingManager.Parent as FrameworkElement;
                    ResourceDictionary themeDictionary = new ResourceDictionary();
                    themeDictionary.Source = new Uri(newTheme.GetResourceUri().ToString(), UriKind.Relative);
                    Brush _accentBrush = themeDictionary["AvalonDock_ThemeMetro_BaseColor3"] as Brush;
                    MetroLightThemeResourceDictionary lightTheme = new MetroLightThemeResourceDictionary(_accentBrush);
    
                    if (!string.IsNullOrEmpty(Xceed.Wpf.Toolkit.Licenser.LicenseKey))
                    {
                        lightTheme.LicenseKey = Xceed.Wpf.Toolkit.Licenser.LicenseKey;
                    }
    
                    parent.Resources.MergedDictionaries.Clear();
                    parent.Resources.MergedDictionaries.Add(lightTheme);
                    parent.Resources.MergedDictionaries.Add(new Xceed.Wpf.Toolkit.Themes.Metro.ToolkitMetroLightThemeResourceDictionary(_accentBrush));
    

    For the most part the theme works when i do not have to over-write the styles
    for elements. However, for any items that are binded dynamically from a view model,
    and has it own style, it does not follow the loaded theme’s style. I know that the problem
    is that I’m not basing my local style with the local theme style, but I do not know
    which style to inherit it from.

    Here’s an example:
    My tree view item is binded from its view model but it’s not inheriting the styles of the theme … what should my style be based on?

                <TreeView.ItemContainerStyle>
                    <Style TargetType="{x:Type TreeViewItem}" BasedOn="??">
                        <Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" />
                        <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
                        <Setter Property="FontWeight" Value="Normal" />
                        <Style.Triggers>
                            <Trigger Property="IsSelected" Value="true">
                                <Setter Property="FontWeight" Value="Bold" />
                            </Trigger>
                        </Style.Triggers>
                    </Style>
                </TreeView.ItemContainerStyle>
    

    Thanks,
    Daniel.

    Fawzi [Xceed]
    Member
    Post count: 722

    Hi,

    When changing to Metro Theme, the TreeView is themed, along with its ItemContainerStyle(or TreeViewItem).
    If you set a specific style for “TreeView.ItemContainerStyle”, you override the metro themed TreeView.ItemContainerStyle with yours, based on System type. You cannot base this style on a dynamic system type in XAML. So the TreeViewItem is not themed in Metro.

    What you could do if you want to dynamically change the theme is to set your TreeViewItem style in the Resources of the Window and give it a key. Then, create another resource : an implicit style for TreeView with its property ItemContainerStyle using a dynamicResource to reference the TreeViewItem key resource.

    This will override TreeView.ItemContainerStyle property and you won’t see a change when switching to Metro Theme. Nothing new here. But since the reference is DynamicResource, modifiying the TreeViewItem style should do the job.

    This can be done in code-behind.

    Since we can’t modify the “BasedOn” property of an active style, we should create a new style (with the same Setters and Triggers), but based it on the new metro TreeViewItem style. Then, removing the TreeViewItem style from the Resources and adding the newly created one should do it.

    In XAML :

    <Window.Resources>
    <Style x:Key=”TreeViewItemStyle”
    TargetType=”{x:Type TreeViewItem}”>
    <Setter Property=”IsExpanded”
    Value=”{Binding IsExpanded, Mode=TwoWay}” />
    <Setter Property=”IsSelected”
    Value=”{Binding IsSelected, Mode=TwoWay}” />
    <Setter Property=”Header”
    Value=”{Binding Name}” />
    <Setter Property=”FontWeight”
    Value=”Normal” />
    <Style.Triggers>
    <Trigger Property=”IsSelected”
    Value=”true”>
    <Setter Property=”FontWeight”
    Value=”Bold” />
    </Trigger>
    </Style.Triggers>
    </Style>

    <Style TargetType=”TreeView”>
    <Setter Property=”ItemContainerStyle”
    Value=”{DynamicResource TreeViewItemStyle}” />
    </Style>
    </Window.Resources>

    <TreeView ItemsSource=”{Binding Items}”/>

    and in code-behind :

    private void Button_Click( object sender, RoutedEventArgs e )
    {
    Theme newTheme = new Xceed.Wpf.AvalonDock.Themes.MetroTheme();
    dockingManager.Theme = newTheme;

    var parent = dockingManager.Parent as FrameworkElement;
    var themeDictionary = new ResourceDictionary();
    themeDictionary.Source = new Uri(newTheme.GetResourceUri().ToString(), UriKind.Relative);
    var _accentBrush = themeDictionary[“AvalonDock_ThemeMetro_BaseColor3”] as Brush;
    var lightTheme = new MetroLightThemeResourceDictionary(_accentBrush);

    if ( !string.IsNullOrEmpty(Xceed.Wpf.Toolkit.Licenser.LicenseKey) )
    {
    lightTheme.LicenseKey = Xceed.Wpf.Toolkit.Licenser.LicenseKey;
    }

    var defaultTreeViewItemStyle = this.Resources[“TreeViewItemStyle”] as Style;

    this.Resources.MergedDictionaries.Clear();
    this.Resources.MergedDictionaries.Add(lightTheme);
    this.Resources.MergedDictionaries.Add(new Xceed.Wpf.Toolkit.Themes.Metro.ToolkitMetroLightThemeResourceDictionary(_accentBrush));

    var metroTreeViewItemStyle = this.Resources[typeof(TreeViewItem)] as Style;

    //Create a new TreeViewItem style based on metro TreeViewItem style
    var newTreeViewItemStyle = new Style(typeof(TreeViewItem));
    foreach ( var setter in defaultTreeViewItemStyle.Setters )
    {
    newTreeViewItemStyle.Setters.Add(setter);
    }
    foreach ( var trigger in defaultTreeViewItemStyle.Triggers )
    {
    newTreeViewItemStyle.Triggers.Add(trigger);
    }
    newTreeViewItemStyle.BasedOn = metroTreeViewItemStyle;
    this.Resources.Remove(“TreeViewItemStyle”);
    this.Resources.Add(“TreeViewItemStyle”, newTreeViewItemStyle);
    }

Viewing 2 posts - 1 through 2 (of 2 total)
  • You must be logged in to reply to this topic.