Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using MahApps IconPacks for BackstageTabItem's icon #782

Closed
537mfb opened this issue Mar 16, 2020 · 19 comments
Closed

Using MahApps IconPacks for BackstageTabItem's icon #782

537mfb opened this issue Mar 16, 2020 · 19 comments
Assignees
Labels
Milestone

Comments

@537mfb
Copy link

537mfb commented Mar 16, 2020

Not sure if this is an issue or just something i'm missing

I'm using both Fluent.Ribbon and MahApps IconPacks for a project
I wan0t to use an element of IconPacks as the Icon for the backstage tabItems

Here's a sample:

<Fluent:BackstageTabItem Header="Settings" Icon={iconPacks:Material kind=Settings}" />

But while the header text shows in white (expected) the icon shows IN black (unexpected)

Is there a way to make the Icon color match the text color?
All examples i found use images rather then the IconsPack for these icons

Environment

  • Fluent.Ribbon v7.0.1
  • MahApps.Metro.IconPacks v.3.4.0
  • Windows 10 v1909
  • .NET Core 3.1
@batzen
Copy link
Member

batzen commented Mar 24, 2020

@punker76 How does that work for the icon packs?

@537mfb
Copy link
Author

537mfb commented Mar 24, 2020

The IconsPack takes whatever color is set for foreground in the control

in fact if i set Foreground="red" in Fluent:BackstageTabItem, the icon turns red while the text remains white - however i haven't figured out a way to bind Foreground to the text's color

I assume it's using Fluent.Ribbon.Brushes.BackstageTabItem.Header.Foreground (from the name), but using this as DynamicResource in Foreground throws an exception that it can't convert it to the type of property Foreground. Using StaticResource seems to work but if then i change theme (between yellow and blue for exemple) it doesn't update

@punker76
Copy link
Member

@punker76 How does that work for the icon packs?

@batzen How gets the icon ContentPresenter the Foreground?

<ContentPresenter x:Name="iconImage"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Width="16"
Height="16"
Margin="0 0 8 0"
Content="{converters:ObjectToImageConverter {Binding Icon, RelativeSource={RelativeSource TemplatedParent}}, '16,16', {Binding RelativeSource={RelativeSource TemplatedParent}}}"
SnapsToDevicePixels="True" />

And what exactly does the ObjectToImageConverter? If I understand this correct then it tries to convert the Icon property to an ImageSource?

@batzen
Copy link
Member

batzen commented Mar 24, 2020

The ContentPresenter should inherit it's foreground from the parent.

And what exactly does the ObjectToImageConverter?

A lot. It tries to convert everything it gets to something that could be an image.

I will try to reproduce the issue by including the icon packs in the showcase application and see what has to be done to get this working correctly.

@batzen
Copy link
Member

batzen commented Mar 24, 2020

The issue is caused by the logical tree.
To support bindings inside the potential icon i have to add the icon to the logical tree of the tab item which inherits from ContentControl. This causes dependency property inheritance to break because the LogicalChildren implementation of ContentControl has a bug and does not return the logical children from it's base class.
I will work around this by overriding the LogicalChildren property here, but it's gonna take some time as i have to finish the ThemeManager stuff in ControlzEx first and i will have to override that property in every control that also indirectly inherits from ContentControl, which includes CheckBox, Button etc..

@batzen batzen self-assigned this Mar 24, 2020
@batzen batzen added this to the Next milestone Mar 24, 2020
@537mfb
Copy link
Author

537mfb commented Mar 24, 2020

@batzen That's quite an undertaking. I haven't looked at the code but wouldn't it be easier/faster to have BackstageTabItem.Foreground match the text color?

Given changing the Foreground property currently affects the icon (but not the text), if the text color becomes bound to the control's Foreground property, and the Foreground property set to the correct resource in a dynamic way (in the template), this should be fixed without the need to support binding in the icon - it just inherits the control's Foreground as it does now.

Or am I missing something?

@537mfb
Copy link
Author

537mfb commented Mar 24, 2020

May have found something - am getting a bunch of errors so haven't been able to test it

in file Themes\Controls\BackstageTabItem.xaml you have:

<Style x:Key="BackstageTabItemStyle" TargetType="{x:Type Fluent:BackstageTabItem}">
...
<Setter Property="Foreground" Value="{DynamicResource BlackBrush}" />
...
</Style>

I am assuming changing that Foreground definition from BlackBrush to Fluent.Ribbon.Brushes.BackstageTabItem.Header.Foreground should solve the issue.

Any reason for that beeing set to BlackBrush?

@batzen
Copy link
Member

batzen commented Mar 25, 2020

The icon already supports bindings, but that prevents dependency property inheritance due to the bug in contentcontrol.

BlackBrush turns to white in the dark theme and the inverse for WhiteBrush (it turns black in the dark theme). So changing that doesn't make sense 😉
Even setting foreground to white on the contentpresenter containing the icon doesn't work, so i really have to fix the underlying issue...

@batzen
Copy link
Member

batzen commented Mar 25, 2020

After further investigation it turned out that adding the icon to the logical tree was the wrong part, so instead of having to implement more code i have to delete a lot of code that's not even required and never was... That part of the ribbon was written before i inherited it and thought the original authors had a reason to add the icon to the logical tree, but there is none i can think of.

@batzen batzen modified the milestones: Next, 8.0.0 Apr 26, 2020
@batzen
Copy link
Member

batzen commented Apr 27, 2020

@537mfb just pushed the changes to develop.

@batzen batzen closed this as completed May 2, 2020
@batzen
Copy link
Member

batzen commented May 21, 2020

@537mfb I have to reopen this as not adding the icon to the logical tree causes issues when using bindings with EelementName inside icons.
I will revert the changes made to fix your issue and find a solution that fixes all issues...

@batzen batzen reopened this May 21, 2020
@537mfb
Copy link
Author

537mfb commented May 21, 2020

@batzen that's ok
Guess it wasn't as simple as initialy believed - happens

wound changing the ContentPresenter to something like <ContentPresenter x:Name="iconImage" TextBlock.Foreground="{DynamicResource ...}" ... /> using the same resource used for the text work?

Or in alternative bind to the fluent:BackstageTabItem's Foreground and people could us that to set the color dynamically?

@batzen
Copy link
Member

batzen commented May 21, 2020

I want it work out of the box without have to apply any kind of workaround on the consumer side.
The first thing i will am doing right now is write unit tests that will ensure that things work as expected in all cases i know of and that future controls etc. are checked for these kind of issues automatically.

Ensuring that everything adheres to the logical tree rules seems way easier than adding your suggested workaround to every control and telling people that if they are creating their own styles that they also have to apply that workaround in their custom styles/templates. ;-)

@537mfb
Copy link
Author

537mfb commented May 21, 2020

Good point

If i have any other ideias i'll pitch them here to get your feedback

@batzen
Copy link
Member

batzen commented May 21, 2020

You misunderstood me. I already have a working solution on my machine. I just need to finish the unit tests. 😁

@537mfb
Copy link
Author

537mfb commented May 6, 2021

FYI: this is still not working as expected
image

Fluent.Ribbon v8.0.3
MahApps.Metro v2.4.5
MahApps.Metro.IconPacks v4.8.0

@punker76
Copy link
Member

punker76 commented May 6, 2021

@537mfb I will fix/feature this on IconPacks itself, so that it use the inherited Foreground form the VisualParent. A workaround for this is to use a DataTemplate with the IconPack inside.

@537mfb
Copy link
Author

537mfb commented May 6, 2021

Hi @punker76 - thanks for the reply

Ok did a new test
<Fluent:BackstageTabItem Header="Settings" Icon="{iconPacks:Material Kind=Cog}" Foreground="{DynamicResource Fluent.Ribbon.Brushes.Backstage.Foreground}">

this makes it work - even if i change the theme live
tried changing from light blue to light yellow and back at the press of a button and the color correctly changed from black to white according to the theme

@kwon0408
Copy link

kwon0408 commented Jul 1, 2022

<Fluent:BackstageTabItem Header="Settings" Icon="{iconPacks:Material Kind=Cog}" Foreground="{DynamicResource Fluent.Ribbon.Brushes.Backstage.Foreground}">

For whom reading this in future: As of now, this code makes tab content's default foreground color overridden by the given value.

E.g. If Foreground is set to Red, any element in the tab having an unset Foreground property will be displayed in red color.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants