I have the following custom control,
public sealed class MediaFileItemControl : Control
{
public static readonly DependencyProperty MediaFileProperty =
DependencyProperty.Register(nameof(MediaFile), typeof(StorageFile), typeof(MediaFileItemControl), new PropertyMetadata(null));
public MediaFileItemControl()
{
DefaultStyleKey = typeof(MediaFileItemControl);
}
public StorageFile MediaFile
{
get => (StorageFile)GetValue(MediaFileProperty);
set => SetValue(MediaFileProperty, value);
}
}
the following style for it,
<!-- Generic.xaml -->
<Style TargetType="controls:MediaFileItemControl" >
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="controls:MediaFileItemControl">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{TemplateBinding MediaFile.Name}" />
<TextBlock Text="{TemplateBinding MediaFile.Path}" />
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
and lastly, I want to use it within a ListBox
, something like:
<ListBox ItemsSource="{x:Bind ViewModel.MediaFiles, Mode=OneWay}">
<ListBox.ItemTemplate>
<DataTemplate x:DataType="win_storage:StorageFile" xmlns:win_storage="using:Windows.Storage">
<controls:MediaFileItemControl MediaFile="{x:Bind}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
However, when I build the project, I get the following error in Generic.xaml
The XAML Binary Format (XBF) generator reported syntax error '0x80004005'
Where is the syntax error and what is the right way to achieve what I want?
x:Bind has lots of issues that are quite difficult to overcome: https://github.com/microsoft/microsoft-ui-xaml/issues/2508
But you can use a ContentControl
that points to a DataTemplate
. So in your case, you can write it like this:
<ResourceDictionary
x:Class="MyWinUIApp.ResourceDictionary1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:MyWinUIApp"
xmlns:storage="using:Windows.Storage">
<DataTemplate x:Key="StorageFileTemplate" x:DataType="storage:StorageFile">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{x:Bind Name}" />
<TextBlock Text="{x:Bind Path}" />
</StackPanel>
</DataTemplate>
<Style TargetType="local:MediaFileItemControl">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<ContentControl ContentTemplate="{StaticResource StorageFileTemplate}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
Note I've create a custom ResourceDictionary
as it doesn't seen to work in the App.xaml one for another mysterious reason. Make sure you create one with a code-behind to support x:Bind as explained here: Resource dictionaries with {x:Bind}
If you don't want that complexity, you can still use the ole Binding
markup extension wich often works where the so-called "better" x:Bind
fails:
<Style TargetType="local:MediaFileItemControl">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}" />
<TextBlock Text="{Binding Path}" />
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>