-
Notifications
You must be signed in to change notification settings - Fork 49
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
[MVUX] Custom Control Style not set properly when bound to the model #2400
Comments
Hummm, for me the issue is here: public IListState<Item> Items => ListState<Item>.Value(this, () =>
[
new Item("Item A", StyleFactory.CreateStyle("Style A from model", Colors.Red)),
new Item("Item B", StyleFactory.CreateStyle("Style B from model", Colors.Green)),
new Item("Item C", StyleFactory.CreateStyle("Style C from model", Colors.Blue)),
]); The delegate is expected to be invoked from a background thread, that's why the style does not work at all on windows, and might have some weird behaviors with uno (where we are not validating the UI thread as strongly as windows). The |
Generally, However, somehow, this is now working (given the latest bug fixes on C# Markup) on both WinAppSDK and Uno. But I agree with David that this feels wrong and you probably shouldn't rely on things running that way. For Uno specifically, accessing the DP system on background thread may appear like it's working, but can then show random race conditions that are hard to track down. Such race conditions in Uno can end up storing a DP value in place of another, then when the other one is read you can end up with incorrect value or even InvalidCastException, etc. |
thanks @dr1rrb @Youssef1313 Q1: could someone help and provide the corrected code for |
@kucint What I'm seeing currently is that the code is actually run on the UI thread, so it will be currently working with latest C# Markup dev releases (using latest Uno.Sdk dev). I'll leave it to @dr1rrb to comment on the MVUX part on whether it was expected that the delegate is run on the UI thread or not, and how to properly write the |
Hey @kucint this is only about creating the style on the dispatcher. You ave 2 options: 1. Embed the dispatcher in the StyleFactoryFor this you have to convert your internal class StyleFactory(DispatcherQueue Dispatcher)
{
/* .../.. */
public ValueTask<Style<MyControl>> CreateStyle(string txt, Color color) => Dispatcher.ExecuteAsync(async () => new Style<MyControl>()
.Setters(s => /* .../.. */);
} And then your model internal partial record MainPageModel(StyleFactory Styles)
{
public IState<Style> Style => State<Style>.Async(this, async _ => await Styles.CreateStyle("Style from model", Colors.HotPink));
public IListState<Item> Items => ListState<Item>.Async(this, async _ =>
[
new Item("Item A", await Styles.CreateStyle("Style A from model", Colors.Red)),
new Item("Item B", await Styles.CreateStyle("Style B from model", Colors.Green)),
new Item("Item C", await Styles.CreateStyle("Style C from model", Colors.Blue))
]);
} 2. Defer to the caller the responsibility to invoke the factory on the right threadIn your case this means to inject the dispatcher in the internal partial record MainPageModel(DispatcherQueue Dispatcher)
{
public IState<Style> Style => State<Style>.Value(this, () => StyleFactory.CreateStyle("Style from model", Colors.HotPink));
public IListState<Item> Items => ListState<Item>.Async(this, async _ => await Dispatcher.ExecuteAsync(async () => ImmutableList.Create(
new Item("Item A", StyleFactory.CreateStyle("Style A from model", Colors.Red)),
new Item("Item B", StyleFactory.CreateStyle("Style B from model", Colors.Green)),
new Item("Item C", StyleFactory.CreateStyle("Style C from model", Colors.Blue))
)));
} |
@dr1rrb, I see what you mean. thanks! |
@kucint can this be closed? |
I did not try the proposed solution, but ... I guess, yes. |
Discussed in #2372
Originally posted by kucint June 20, 2024
Let´s create a simple Control:
Style for this control is created dynamically as follows:
Lest consume now the control and apply different styles to it:
Model:
In most of the cases, dynamically generated
Style
is applied as expected, but not when it comes from bound MVU model:Tested on Windows:
net8.0-desktop;
Note that when run on Windows with
net8.0-windows10.0.19041;
control does not render at all.But this is another issue....
Uno version:
"Uno.Sdk": "5.2.161"
Repro: UnoStyleAsPropertyApp.zip
Note that in the example above all styles are instantiated in the control so the
static
styles are nor created at all.This is due to avoid interference with another issue #2349
The text was updated successfully, but these errors were encountered: