To reduce load time or to increase layout performance one may need to conditionally detach layout controls from visual tree. For example, when layout part loads images from the Net, but a user has disabled image loading in the application settings, XAML layout does not need to load the view part responsible for image showing.
In Angular, there is a NgIf directive that solves this issue. So please, take a look: https://angular.io/api/common/NgIf
Moreover, I've implemented an UwpIf control for Uwp recently: https://github.com/worldbeater/myFeed/blob/master/myFeed.Uwp/Controls/UwpIf.cs
So, maybe Avalonia framework should have such control in its standard library? Something named AvalonIf that we can use in our application like this:
<AvalonIf Value="{Binding ShouldLoad, Mode=OneWay}">
<Image Source="{Binding Image, Mode=OneTime}"/>
</AvalonIf>
Thanks!
I think this can be achieved easily by binding to Visibility property, no need for a separate control.
I think this can be achieved easily by binding to Visibility property, no need for a separate control.
Changing Visibility to _collapsed_ or _hidden_ only hides the control so a user does not see it, but it doesn't detach it from visual tree, so images will continue loading in background and controls will get eagerly initialized.
Interesting. I've never needed such a thing, perhaps because I tend to use MVVM, so if images are disabled then that would be done at the ViewModel level.
I'm not sure if this would be a common enough case to include the control in the core library. Do you have any more examples?
I think that something like that could be naturally achieved using ContentControl and DataTemplates: set the DataTemplate to some dummy value when you don't want to see the data (it won't even bother to create the controls from the "wrong" DataTemplate, and that's exactly what you need). It will require a bit of MVVM programming or TemplateSelector though.
I tend to use MVVM, so if images are disabled then that would be done at the ViewModel level.
But how to implement this using MVVM? As for now, I read settings using Load command and expose a property named ImagesEnabled from my ViewModel — so the UI knows if images are disabled and can easily detach unnecessary controls off using such conditional XAML control.
Are there any other ways of doing this? I thought of spoiling image urls — but this is a dirty solution. Another way is to write a custom control inherited from Image that won't load content until a special flag is set — but this solution is not universal — what if I need square images, round images, triangle images (Illuminati will appreciate), or videos.
Creating content controls with several DataTemplates seems to be a working solution (thanks, @ForNeVeR), but a bit complicated for such a simple task as conditionaly showing/hiding elements!
I'm not sure if this would be a common enough case to include the control in the core library. Do you have any more examples?
Frankly speaking, I could hardly imagine any other cases where conditional XAML will be the only way to go, so including this feature in the core library may not be really necessary @grokys! But in the future, it can potentially simplify one's codebase. :)
_Note: First let me say that I've never run into this particular case so I could be missing something!_
Ok, so the way I would do it would just be to expose a null for the image source/URL from the view model when ImagesEnabled == false. If you look at the source for Image you can see that the control pretty much does nothing when Source == null so there should be no overhead other than the control being added to the tree.
And note that if you were to use an <AvaloniaIf> control, _that control would still be added to the tree_, so you're back to the same place as just adding an <Image> with a null Source. If we want to be able to not create a particular sub-tree if a condition is set, then that would require XAML support I think.
If you have other examples though, please let me know!
UWP has build in x:DeferLoadStrategy attribute for lazy loading and x:Load attribute (Creators Update+) for loading and unloading with binding, which can replace UwpIf/AvaloniaIf
<Grid>
<Image x:Name="MyImage"
x:DeferLoadStrategy="Lazy"
Source="{Binding Image, Mode=OneTime}"
Visibility="Collapsed"/>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup>
<VisualState>
<VisualState.StateTriggers>
<StateTrigger IsActive="{Binding ShouldLoad, Mode=OneWay}"/>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="MyImage.Visibility"
Value="Visible"/>
</VisualState.Setters>
</VisualState>
</VisualStateManager.VisualStateGroups>
</Grid>
Or
<Image x:Load="{Binding ShouldLoad, Mode=OneWay}"
Source="{Binding Image, Mode=OneTime}"/>
Also UWP has Conditional XAML using namespaces. But it seems to solve other problems.
Most helpful comment
UWP has build in x:DeferLoadStrategy attribute for lazy loading and x:Load attribute (Creators Update+) for loading and unloading with binding, which can replace UwpIf/AvaloniaIf
Or