❔ [Avalonia] Basic question regarding subclassing
Let's say I have some types like so:
I'd like to display a
List<Foo>
where FooA
s and FooB
s would be displayed completely differently.
Just as a random example, FooA
would simply display "This is a FooA" with a red background while FooB
would display "This is a FooB with name '...' and age '...' " in a blue background. You get the idea.
The way I envision this is that FooA
and FooB
would themselves define how they should be displayed.
I would be really grateful if someone could break this down to me. Bonus points if there's a working example.40 Replies
You could create a
DataTemplate
for each type:
https://docs.avaloniaui.net/docs/templates/data-templatesData Templates | Avalonia UI
Many controls have a Content property, such as ContentControl.Content. Window inherits from ContentControl, so lets use that as an example. You're probably familiar with what happens when you put a control in the Window.Content property - the window displays the control:
I'm really unfamiliar with all these concepts so please correct me if I'm wrong, but isn't this more of a workaround? I don't necessarily need to display the objects directly.
Like I could define views or controls or whatever, it doesn't have to be exactly the data types I've written
I just don't know how to wire this all up
to be clear, I'm like 45 minutes into avalonia, I know basically nothing. The only UI experience I have is like React and Svelte
Thanks for the help btw
No, I don't it's a workaround. That's what data templates are for
generally with frameworks like this the business and presentation details are kept separate
in this example your data is your model or viewmodel, and then your view will bind to that and the view is where you specify how things should actually appear
You could do that, but you'd still need to put the views in data templates
Ok, so would I define one View per subclass in this case? I'm really having trouble understanding how to apply that knowledge to this specific example
I mostly understand the model-viewmodel-view distinction conceptually
but it's not clear to me how to apply it in this specific case
for a collection afaik data templates are the way to go
you can define them as part of your view and i think it will automatically select one to use based on the object type
check what noho posted, i'm a bit rusty with xaml
Alright, thanks to both of you @Jimmacle @nohopestage 😄
Someone also suggested this
In this instance, the simplest (but definitely not the only) way to do this would be to add a method to Foo, public Control Draw(). Each implementation would have to override this function and handle drawing all the details, so woops, still typing You would also define the XAML somewhere, so if you want a specific layout for FooA, you would need to make FooAControl. FooBControl would need some elements that you can Bind the properties to. In the Draw method of each, you would create and return a new instance of the control that's created and then bind the properties as necessary. Then, just append the Controls to whatever it is that's iterating the elements.Does that make sense or...? because it sounds really different from what you're suggesting
that is very different, that sounds like a very manual way of doing it compared to taking advantage of what's already there to help you
^
alright, makes sense
in a perfect world the only code directly related to UI would be done in xaml with no code-behind
besides writing custom controls, anyway
so you're saying that I should push as much stuff as possible to XAML?
There's nothing wrong with code-behind though, as long as it's related to the UI
yeah, i try to minimize it regardless
the main thing is not mixing your business logic with UI code
That makes sense.
In the other GUIs I worked with, I could basically do stuff like this directly in the markup (would be XAML in this case)
I don't think conditionals are allowed in XAML so this kind of changes things for me
but I'll try data templates and see how things go
You could do that with a custom
DataTemplate
class, but I'd just create two data templates in xamlThanks again for all the help, I'll give it a shot 😄
Is there a way to define like smaller fragments of XAML? For example, what if my data template is very complex (lots of markup). Wouldn't that make the xaml files really difficult to read?
Yeah, you can put the template in a
ResourceDictionary
I believeResources | Avalonia UI
Often, styles and controls will need to share resources such as (but not limited to) brushes and colors. You can put such resources in the Resources dictionary which is available on every style and control and then refer to these resources elsewhere.
Actually, I think you have to create a
DataTemplates
file and use DataTemplateInclude
A DataTemplates file? 🤔
Yeah, if you have the Avalonia extension installed it might be an option in the add file dialog. If not, here's what it should look like:
https://github.com/AvaloniaUI/Avalonia/discussions/8426#discussioncomment-4627825
GitHub
How to share DataTemplate s across projects? · AvaloniaUI Avalonia ...
In WPF I can put the DataTemplates in ResourceDictionary and merge it in other application. But in Avalonia there are many limits: DataTemplates can't be put in ResourceDictionary without key. ...
doesn't seem like it? 🤔
Just create a new file then
Just to back track for a sec, I read the section on DataTemplate, but I still did not really understand how I'm supposed to make that work
For example, I tried this:
obviously this is not doing what I think it is
You can only have a single
DataTemplate
in ItemsControl.ItemTemplate
. You can put both in ItemsControl.Resources
So, something like this?
how do I use these resources afterwards?
They should apply automatically
this is what I have currently, so again I must be doing something wrong
I get this:
You can remove
ItemsControl.ItemTemplate
. Other than that seems okI removed it, same error it seems
Sorry, it should be
ItemsControl.DataTemplates
instead of ItemsControl.Resources
Oh yeah now it compiles! Thanks
Hurray, everything works as intended. Thanks a lot.
Was this issue resolved? If so, run
/close
- otherwise I will mark this as stale and this post will be archived until there is new activity.