I have 6 DataTemplate for this API. API is a enum.
public enum ShimmerType
{
CirclePersona,
SquarePersona,
Profile,
Article,
Video,
Feed,
Shopping,
}
API name is Type. I defined this property in below of my shimmer control.
public ShimmerType Type
{
get { return (ShimmerType)GetValue(TypeProperty); }
set { SetValue(TypeProperty, value); }
}
// Using a DependencyProperty as the backing store for Type. This enables animation, styling, binding, etc...
public static readonly DependencyProperty TypeProperty = DependencyProperty.Register("Type", typeof(ShimmerType), typeof(SfShimmer), new PropertyMetadata(ShimmerType.CirclePersona,OnTypePropertyChangedMethod));
In my ShimmerControl.XAML:
I have given a sample data template for your understanding.
<DataTemplate x:Key="ShimmerFeedTemplate">
<!--Blah Blah blah -->
</DataTemplate>
<DataTemplate x:Key="ShimmerCirclePersonaTemplate">
<!--Blah Blah blah -->
</DataTemplate>
<DataTemplate x:Key="ShimmerArticleStyle">
<!--Blah Blah blah -->
</DataTemplate>
<DataTemplate x:Key="ShimmerProfileTemplate">
<!--Blah Blah blah -->
</DataTemplate>
<DataTemplate x:Key="ShimmerShoppingTemplate">
<!--Blah Blah blah -->
</DataTemplate>
<DataTemplate x:Key="ShimmerVideoTemplate">
<!--Blah Blah blah -->
</DataTemplate>
Shimmer Style:
I've given you a control templates in the Shimmer style. I have provided content template as CirclePersona template by with shimmer control.
<Style x:Key="ShimmerStyle" TargetType="local:Shimmer">
<Setter Property="HorizontalAlignment" Value="Center"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="Fill" Value="{ThemeResource ShimmerFillColor}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:Shimmer">
<StackPanel>
<ContentControl x:Name="Grid1">
<ContentPresenter x:Name="presenters" ContentTemplate="{StaticResource ShimmerCirclePersonaTemplate}" />
</ContentControl>
<Grid x:Name="Grid2">
<ContentControl>
<ContentPresenter Content="{TemplateBinding Content}"/>
</ContentControl>
</Grid>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
How to change the DataTemplate of my Control ContentPresenter to according the Type API .I have set a separate datatemplate for each enum type API.
I have Try below this:
public class SfShimmer:Control
{
public SfShimmer()
{
this.DefaultStyleKey= typeof(SfShimmer);
}
internal ContentPresenter Presenter;
public ShimmerType Type
{
get { return (ShimmerType)GetValue(TypeProperty); }
set { SetValue(TypeProperty, value); }
}
public static readonly DependencyProperty TypeProperty =
DependencyProperty.Register("Type", typeof(ShimmerType), typeof(SfShimmer), new PropertyMetadata(ShimmerType.CirclePersona,OnTypePropertyChangedMethod));
protected override void OnApplyTemplate()
{
this.Presenter = this.GetTemplateChild("presenters") as ContentPresenter;
base.OnApplyTemplate();
this.Loaded += SfShimmer_Loaded;
}
private static void OnTypePropertyChangedMethod(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
SfShimmer sfShimmer = d as SfShimmer;
ContentPresenter pr = sfShimmer.Presenter;
if (pr != null)
{
DataTemplate dataTemplate = null;
switch (sfShimmer.Type)
{
case ShimmerType.Feed:
dataTemplate = sfShimmer.Resources["ShimmerFeedControlTemplate"] as DataTemplate;
break;
case ShimmerType.Profile:
dataTemplate = sfShimmer.Resources["ShimmerProfileTemplate"] as DataTemplate;
break;
case ShimmerType.Video:
dataTemplate = sfShimmer.Resources["ShimmerVideoTemplate"] as DataTemplate;
break;
case ShimmerType.Shopping:
dataTemplate = sfShimmer.Resources["ShimmerShoppingTemplate"] as DataTemplate;
break;
default:
dataTemplate = sfShimmer.Resources["ShimmerFeedControlTemplate"] as DataTemplate;
break;
}
pr.ContentTemplate = dataTemplate;
}
}
}
I tried this but no progress. In WinUI MainWindow.Xaml I specified this API like below:
<Window
x:Class="WinUI_3_SFShimmer_control.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:WinUI_3_SFShimmer_control"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
xmlns:shim="using:Shimmer.WinUI">
<Grid>
<shim:Shimmer x:Name="shimmer" Type="Profile" />
</Grid>
</Window>
The dataTemplate should be the same as the contenttemplate of my content control, depending on what type I give to my Type API in the mainwindow.xaml. How in WinUI C#?
You can create yourown DataTemplateSelector
.
This is a simple example based on a bit of your code:
public enum ShimmerType
{
CirclePersona,
SquarePersona,
Profile,
}
public class ShimmerTemplateSelector : DataTemplateSelector
{
public DataTemplate? CirclePersonaTemplate { get; set; }
public DataTemplate? SquarePersonaTemplate { get; set; }
public DataTemplate? ProfileTemplate { get; set; }
protected override DataTemplate? SelectTemplateCore(object item)
{
return (item as CustomButton)?.ShimmerType switch
{
ShimmerType.CirclePersona => CirclePersonaTemplate,
ShimmerType.SquarePersona => SquarePersonaTemplate,
ShimmerType.Profile => ProfileTemplate,
_ => base.SelectTemplateCore(item),
};
}
}
public class CustomButton : Button
{
public static readonly DependencyProperty ShimmerTypeProperty =
DependencyProperty.Register(
nameof(ShimmerType),
typeof(ShimmerType),
typeof(CustomButton),
new PropertyMetadata(ShimmerType.CirclePersona, OnShimmerTypePropertyChanged));
public ShimmerType ShimmerType
{
get => (ShimmerType)GetValue(ShimmerTypeProperty);
set => SetValue(ShimmerTypeProperty, value);
}
private static void OnShimmerTypePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is CustomButton button)
{
button.ContentTemplate = button.ContentTemplateSelector.SelectTemplate(button);
}
}
}
<MainWindow
...
...>
<Grid>
<Grid.Resources>
<DataTemplate x:Key="CirclePersonaDataTemplate">
<TextBlock Text="CirclePersona" />
</DataTemplate>
<DataTemplate x:Key="SquarePersonaDataTemplate">
<TextBlock Text="SquarePersona" />
</DataTemplate>
<DataTemplate x:Key="ProfileDataTemplate">
<TextBlock Text="Profile" />
</DataTemplate>
<local:ShimmerTemplateSelector
x:Key="ShimmerTemplateSelector"
CirclePersonaTemplate="{StaticResource CirclePersonaDataTemplate}"
ProfileTemplate="{StaticResource ProfileDataTemplate}"
SquarePersonaTemplate="{StaticResource SquarePersonaDataTemplate}" />
</Grid.Resources>
<Grid>
<local:CustomButton
Content="?"
ContentTemplateSelector="{StaticResource ShimmerTemplateSelector}"
ShimmerType="Profile" />
</Grid>
</Grid>
</MainWindow>