This is a migrated thread and some comments may be shown as answers.

RadRibbonSplitButton & RadToggleButton - not following theme with Custom Content

10 Answers 150 Views
Buttons
This is a migrated thread and some comments may be shown as answers.
Joel
Top achievements
Rank 1
Iron
Joel asked on 28 Mar 2018, 06:05 AM

telerik version: 2018.1.220.40

Theme: Expression Dark 

RadToggleButton with Custom Content - not following theme when it is checked.

<telerik:RadToggleButton IsEnabled="{Binding CanLinkToHandler, Mode=OneWay}"
                         IsChecked="{Binding LinkToHandler, Mode=TwoWay}" Margin="4">
    <StackPanel Orientation="Vertical">
        <Image Source="{Binding LinkIconPath, Mode=OneWay}" Width="64" Height="64"/>
        <TextBlock Text="LinkToHandler" Margin="4 0 4 0" HorizontalAlignment="Center"/>
    </StackPanel>

</telerik:RadToggleButton>

RadRibbonSplitButton with Custom Content - not following theme when user click on the button to display the dropdown content.

<telerik:RadRibbonSplitButton Margin="4">
    <StackPanel Orientation="Horizontal">
        <Image Source="/Lumeresoft;component/Resources/Images/Hamburger icon.png" Width="16" Height="16"/>
        <telerik:Label Content="ManualTrigger:"/>
        <telerik:Label Content="{Binding Multishots, Mode=OneWay}" />
    </StackPanel>

    <telerik:RadRibbonSplitButton.DropDownContent>
         <Grid>
          ...
        </Grid>
</telerik:RadRibbonSplitButton/>

 

Problem with theme on RadRadioButton with custom content

I have tried the approach mentioned in above link, but it does not work for me.

Please let me know what other ways that can be done in order to apply the theme to Custom Content.

10 Answers, 1 is accepted

Sort by
0
Vladimir Stoyanov
Telerik team
answered on 30 Mar 2018, 12:53 PM
Hello Joel,

Thank you for the attached picture and code snippets.

I am attaching a sample project which I used to test the described scenario on my side. With the RadToggleButton I managed to successfully implement the solution provided in the referenced topic. May I ask you to take a look at the attached project and let me know what I am doing differently? As for the RadRibbonSplitButtons, the correct Foreground binding is to the button part of the control which is a RadButton:
Foreground="{Binding RelativeSource={RelativeSource AncestorType=telerik:RadButton},
               Path=Foreground}" />

I hope you find this helpful.

Regards,
Vladimir Stoyanov
Progress Telerik
Want to extend the target reach of your WPF applications, leveraging iOS, Android, and UWP? Try UI for Xamarin, a suite of polished and feature-rich components for the Xamarin framework, which allow you to write beautiful native mobile apps using a single shared C# codebase.
0
Joel
Top achievements
Rank 1
Iron
answered on 02 Apr 2018, 05:30 AM

Hi Vladimir,

  Thanks for the respond & sample project.

   For RadToggleButton, it works well after applying your method.

   For RadRibbonSplitButton, it works when i remove the Visibility property.

   However, when i run it with Visibility property, following exception was thrown when the button is made visible, and the theme was not applied to the custom content.

System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='Telerik.Windows.Controls.RadButton', AncestorLevel='1''. BindingExpression:Path=Foreground; DataItem=null; target element is 'Label' (Name=''); target property is 'Foreground' (type 'Brush')

 

<telerik:RadRibbonSplitButton Margin="4" cal:Message.Attach="[Event Click]=[Action TriggerTestSites()]"
Visibility="{Binding IsShowManualTrigger, Mode=OneWay, Converter={StaticResource trueToVisible}}"
IsEnabled="{Binding CanManualTrigger, Mode=OneWay}">
    <StackPanel Orientation="Horizontal">
        <Image Source="Hamburger icon.png" Width="16" Height="16" ToolTip="{x:Static res:UIStringTable.ConfigureTip}"/>
        <telerik:Label Content="{x:Static res:UIStringTable.ManualTrigger}" ContentStringFormat="{}{0}:"
                 Foreground="{Binding RelativeSource={RelativeSource AncestorType=telerik:RadButton}, Path=Foreground}"/>
        <telerik:Label Content="{Binding Multishots, Mode=OneWay}" ToolTip="{x:Static res:UIStringTable.MultishotsCfgTip}"/>
    </StackPanel>

 

0
Vladimir Stoyanov
Telerik team
answered on 03 Apr 2018, 11:40 AM
Hello Joel,

Thank you for the additional information.

The observed behavior is expected when the RadRibbonSplitButton is not visible since the RelativeSource on the Foreground property of the Label is trying to find a parent of type RadButton. The RadButton is part of the RadRibbonSplitButton and is also not visible.

What I can suggest is to reset the Foreground binding of the Labels when the RadRibbonSplitButton is made visible. A possible approach for that would be to create an attached behavior and set the Foreground binding of the Labels when the IsVisible property of the RadRibbonSplitButton is true. You can handle the IsVisibleChanged event in order to achieve that. I am attaching the sample project modified to demonstrate this approach.

Regards,
Vladimir Stoyanov
Progress Telerik
Want to extend the target reach of your WPF applications, leveraging iOS, Android, and UWP? Try UI for Xamarin, a suite of polished and feature-rich components for the Xamarin framework, which allow you to write beautiful native mobile apps using a single shared C# codebase.
0
Joel
Top achievements
Rank 1
Iron
answered on 12 Apr 2018, 11:54 AM

Hi Vladimir,

  Thanks for the sample project. I will give it a try.

   Meanwhile, can you quickly point out which AncerstorType to apply for RadDropDownButton?

   Thanks.

0
Joel
Top achievements
Rank 1
Iron
answered on 12 Apr 2018, 12:00 PM
I have tried both - AncestorType=telerik:RadButton & AncestorType=ContentPresenter, none of it works.
0
Vladimir Stoyanov
Telerik team
answered on 16 Apr 2018, 02:51 PM
Hello Joel,

Binding RadDropDownButton's Foreground to its parent ContentPresenter works correctly on my side. I am attaching a sample project demonstrating this for your reference. Can you take a look at it and let me know if you are doing something different on your side?

Regards,
Vladimir Stoyanov
Progress Telerik
Want to extend the target reach of your WPF applications, leveraging iOS, Android, and UWP? Try UI for Xamarin, a suite of polished and feature-rich components for the Xamarin framework, which allow you to write beautiful native mobile apps using a single shared C# codebase.
0
Joel
Top achievements
Rank 1
Iron
answered on 18 Apr 2018, 07:19 AM

Hi Vladimir,

  Indeed your sample project works as expected.

  The only difference in my case is that the view is "lazy loaded" i.e. the view is generated by a telerik pane factory (the view is hosted in RadDocking) - this TestActionView is only generated when user click a button, it was not loaded when the application first start.

    i tried your earlier suggested method of using dependency property, but this time it is not working - the dark theme wasn't applied at all. 

<!-- Multishots configuration -->
<telerik:RadDropDownButton IsEnabled="{Binding CanRunSettingDropDown, Mode=OneWay}" Margin="2 4 4 4"
                           b:ForegroundBindingRefreshBehavior.LazyDropDownRefreshBinding="True">
    <StackPanel Orientation="Horizontal">
        <telerik:Label Content="{Binding Currentshot, Mode=OneWay}" />
        <telerik:Label Content="/" Padding="0"/>
        <telerik:Label Content="{Binding Multishots, Mode=OneWay}" ToolTip="{x:Static res:UIStringTable.MultishotsCfgTip}"/>
    </StackPanel>

 

public static bool GetLazyDropDownRefreshBinding(DependencyObject obj)
{
    return (bool)obj.GetValue(LazyDropDownRefreshBindingProperty);
}
 
public static void SetLazyDropDownRefreshBinding(DependencyObject obj, bool value)
{
    obj.SetValue(LazyDropDownRefreshBindingProperty, value);
}
 
 
public static readonly DependencyProperty LazyDropDownRefreshBindingProperty =
    DependencyProperty.RegisterAttached("LazyDropDownRefreshBindingProperty", typeof(bool), typeof(ForegroundBindingRefreshBehavior), new PropertyMetadata(OnLazyDropDownRefreshBinding));
 
private static void OnLazyDropDownRefreshBinding(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    if ((bool)e.NewValue)
    {
        // Note: beware of memory leak when open part file repeatedly.
        var dropDownButton = d as RadDropDownButton;
        dropDownButton.Initialized += DropDownButton_Initialized;
    }
}
 
private static void DropDownButton_Initialized(object sender, EventArgs e)
{
    var dropDownButton = sender as RadDropDownButton;
    UIElementCollection children = (dropDownButton.Content as StackPanel).Children;
    foreach (UIElement child in children)
    {
        SetBinding(child, typeof(ContentPresenter), "TextElement.Foreground");
    }
}
 
private static void SetBinding(UIElement element, Type ancestorType, string propertyPath)
{
    var binding = new Binding() { RelativeSource = new RelativeSource() { AncestorType = ancestorType }, Path = new PropertyPath(propertyPath) };
    if (element is Telerik.Windows.Controls.Label)
    {
        var label = element as Telerik.Windows.Controls.Label;
        label.SetBinding(Telerik.Windows.Controls.Label.ForegroundProperty, binding);
    }
    else if (element is TextBlock)
    {
        var label = element as TextBlock;
        label.SetBinding(TextBlock.ForegroundProperty, binding);
    }
}

 

0
Joel
Top achievements
Rank 1
Iron
answered on 18 Apr 2018, 09:45 AM

Here is the result when i followed your sample project.

<!-- Multishots configuration -->
<telerik:RadDropDownButton IsEnabled="{Binding CanRunSettingDropDown, Mode=OneWay}" Margin="2 4 4 4">
    <StackPanel Orientation="Horizontal">
        <telerik:Label Content="{Binding Currentshot, Mode=OneWay}"
         Foreground="{Binding RelativeSource={RelativeSource AncestorType=ContentPresenter}, Path=(TextElement.Foreground)}"/>
        <telerik:Label Content="/" Padding="0"
          Foreground="{Binding RelativeSource={RelativeSource AncestorType=ContentPresenter}, Path=(TextElement.Foreground)}"/>
        <telerik:Label Content="{Binding Multishots, Mode=OneWay}" ToolTip="{x:Static res:UIStringTable.MultishotsCfgTip} 
               Foreground="{Binding RelativeSource={RelativeSource AncestorType=ContentPresenter}, Path=(TextElement.Foreground)}"/>
0
Vladimir Stoyanov
Telerik team
answered on 20 Apr 2018, 12:48 PM
Hello Joel,

Thank you for the attached pictures.

I was able to reproduce the described scenario on my side. This behavior is related to an issue in the RadTabControl which I logged in our feedback portal: TabControl: RelativeSource bindings in tab item are resolved wrong. The reason that this occurs in the RadDocking control is that the RadPaneGroup inherits RadTabControl. I have updated your telerik points for bringing this to our attention.

What I can suggest as a workaround is to set the ContentTemplate of the RadDropDownButton to a ContentControl and put the custom content in it, like so:
<telerik:RadDropDownButton>
               <telerik:RadDropDownButton.ContentTemplate>
                   <DataTemplate>
                       <ContentControl>
                           <StackPanel Orientation="Horizontal">
                               <telerik:Label Content="Test 2" Foreground="{Binding RelativeSource={RelativeSource AncestorType=ContentControl}, Path=Foreground}" />
                           </StackPanel>
                       </ContentControl>
                   </DataTemplate>
               </telerik:RadDropDownButton.ContentTemplate>
 
           </telerik:RadDropDownButton>

I am attaching a sample project demonstrating this approach for your reference. Please give it a try and let me know if it works in your case.

If you need any further assistance, may I ask you to open a new support ticket and send a sample project demonstrating the issue. This way I will be able to investigate further.

Regards,
Vladimir Stoyanov
Progress Telerik
Want to extend the target reach of your WPF applications, leveraging iOS, Android, and UWP? Try UI for Xamarin, a suite of polished and feature-rich components for the Xamarin framework, which allow you to write beautiful native mobile apps using a single shared C# codebase.
0
Joel
Top achievements
Rank 1
Iron
answered on 27 Apr 2018, 05:56 AM

Hi Vladimir,

   Your suggested workaround is working.

   I need to add DataContext & ElemenetName for the binding to work though. 

<!--Add DataContext & ElementName in order for the Binding to work -->
<telerik:Label Content="{Binding Path=DataContext.Currentshot, Mode=OneWay, ElementName=btnMultishots}"
               Foreground="{Binding RelativeSource={RelativeSource AncestorType=ContentControl}, Path=Foreground}"/>
<telerik:Label Content="/" Padding="0"
               Foreground="{Binding RelativeSource={RelativeSource AncestorType=ContentControl}, Path=Foreground}"/>
<telerik:Label Content="{Binding DataContext.Multishots, Mode=OneWay, ElementName=btnMultishots}" ToolTip="{x:Static res:UIStringTable.MultishotsCfgTip}"
               Foreground="{Binding RelativeSource={RelativeSource AncestorType=ContentControl}, Path=Foreground}"/>

 

  I am looking forward for a fix in future release.

  Thanks.

Tags
Buttons
Asked by
Joel
Top achievements
Rank 1
Iron
Answers by
Vladimir Stoyanov
Telerik team
Joel
Top achievements
Rank 1
Iron
Share this question
or