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

[StyleExtensions] Resources Attached Property #870

Closed
kazo0 opened this issue Jul 31, 2023 · 7 comments · Fixed by #875
Closed

[StyleExtensions] Resources Attached Property #870

kazo0 opened this issue Jul 31, 2023 · 7 comments · Fixed by #875
Assignees
Labels
kind/enhancement New feature or request.

Comments

@kazo0
Copy link
Contributor

kazo0 commented Jul 31, 2023

It would be nice to have a DependencyProperty for Resources. Right now Resources is not a DP so you can't use it in a Setter for a style to say that a specific style should have certain resources defined.

It'd be cool to have an attached property that you can use in a Style.Setter to define a ResourceDictionary where you can put whatever you want. Then I guess we'd need to somehow inject that ResourceDictionary into the Resources of the root control of the ControlTemplate maybe?

One outstanding question is if it is at all possible to be able to access those resources from other Style.Setters on the same Style, sort of like in WPF.

Example:

<Style TargetType="XamlDisplay">
		<Style.Resources>
				<local:XamlFormatter x:Key="IndentedXamlFormatter" />
		</Style.Resources>
		<Setter Property="Formatter" Value="{StaticResource IndentedXamlFormatter}" />
		<Setter Property="Template">
		...
		</Setter>
</Style>
@kazo0 kazo0 added the kind/enhancement New feature or request. label Jul 31, 2023
@Xiaoy312
Copy link
Contributor

Style.Resources wont be possible, but StyleEx.Resources or utu:Style.Resources could be
but ultimately you just want to set the Control.Resources, so you should just create a attached-dp which you use directly to affect that property in the code-behind (as it is not a dp, you cant really use setter with it):

<Setter Property="utu:StyleExtensions.Resources" Value="path-to-my-custom.xaml" />
---
private void StyleExtensions::OnResourcesChanged(object sender, DependencyPropertyCangedArgs e) =>
	(sender as Control).Resources = e.NewValue is string path
		? new ResourceDictionary { Source = path };
		: null;

@Xiaoy312
Copy link
Contributor

directly inline collection item in an attached-dp likely will be problematic too, for both ours and uwp's parser

@Marc-Antoine-Soucy
Copy link
Contributor

Marc-Antoine-Soucy commented Jul 31, 2023

What I have right now in the Xaml:

<RadioButton GroupName="RadioButton_Material_B"
			Content="Overridden Radio Button Style - Unchecked"
			Style="{StaticResource MaterialRadioButtonStyle}"
			local:FrameworkElementExtensions.ResourcePath="ms-appx:///Views/ControlResourcesOverride/Material/RadioButton.xaml" />

You can also change it in a style

<Setter Property="local:FrameworkElementExtensions.ResourcePath"
	     Value="ms-appx:///Views/ControlResourcesOverride/Material/Button.xaml" />

the "ms-appx:///" could be added in the extension code, but I'm not sure if there are times where people would want to use a different kind of prefix.
As for the code in the extension, it's basically this:

private static void OnResourcePathChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
	var control = d as FrameworkElement;
	if (control != null)
	{
		var resourcePath = (string)e.NewValue;
		AddResourcesFromPath(control, resourcePath);
	}
}

private static void AddResourcesFromPath(FrameworkElement control, string resourcePath)
{
	// Load the resource dictionary
	var resources = new ResourceDictionary()
	{
		Source = new Uri(resourcePath, UriKind.RelativeOrAbsolute)
	};

	// Add or replace the resources in this control's resource dictionary
	foreach (var key in resources.Keys)
	{
		if (control.Resources.ContainsKey(key))
                {
			control.Resources[key] = resources[key];
                }
		else
                {
			control.Resources.Add(key, resources[key]);
                }
	}
}

Maybe we don't want that part?

if (control.Resources.ContainsKey(key))
{
	control.Resources[key] = resources[key];
}

@francoistanguay
Copy link
Contributor

just want to set the Con

I would probably put it in ControlExtensions.Resources

@kazo0 kazo0 changed the title Resources Attached Property [ControlExtensions] Resources Attached Property Oct 10, 2023
@agneszitte
Copy link
Contributor

don't forget the documentation that needs to come with it please

@kazo0
Copy link
Contributor Author

kazo0 commented Oct 12, 2023

@Marc-Antoine-Soucy My thinking was more that we would be able to do something like:

<Style TargetType="Button">
	<Setter Property="utu:ControlExtensions.Resources">
		<Setter.Value>
			<ResourceDictionary>
				<StaticResource x:Key="ButtonBackground" ResourceKey="MyRedBrush" />
				<!-- OR -->
				<SolidColorBrush x:Key="ButtonBackground" Color="Red" />
				<!-- OR -->
				<ResourceDictionary.ThemeDictionaries>
					<!--- etc... -->
				</ResourceDictionary.ThemeDictionaries>
			</ResourceDictionary>
			<!-- OR -->
			<ResourceDictionary Source="....." />
		</Setter.Value>

	<Setter Property="Template">
	...
	</Setter>
</Style>

Something like that should theoretically work right @Xiaoy312 ?

@Xiaoy312
Copy link
Contributor

in theory, yes?

@kazo0 kazo0 changed the title [ControlExtensions] Resources Attached Property [StyleExtensions] Resources Attached Property Oct 13, 2023
@kazo0 kazo0 transferred this issue from unoplatform/Uno.Themes Oct 13, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/enhancement New feature or request.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants