Search code examples
c#xamlgridviewbindingwinui-3

GridView conditional binding in WinUI 3


I have two Gridviews to display wallpapers, one for image wallpapers and one for solid color wallpapers.

Now I want to conditionally bind two Gridviews with one "WallpaperCollection"(Contains Both image wallpaper and solid color wallpapers), IsSolidColor value will be used to filter out the wallpapers the Gridview need to display, so, how to do this conditional binding?

GridView for image wallpapers:

 <GridView Name="ImageWallpapers"
     ItemsSource="{x:Bind ViewModel.ImageWallPaperCollection, Mode=OneWay}"
     IsItemClickEnabled="True"
     FlowDirection="LeftToRight"
     SelectionMode="Single"
     IsMultiSelectCheckBoxEnabled="False"
     ItemClick="ImageWallpaperCollection_ItemClick"
     Padding="5,0,5,0">
     <GridView.ItemsPanel>
         <ItemsPanelTemplate>
             <ItemsWrapGrid Orientation="Horizontal"/>
         </ItemsPanelTemplate>
     </GridView.ItemsPanel>
     <GridView.ItemTemplate>
         <DataTemplate x:DataType="Models:Wallpaper">
             <Image Source="{x:Bind ImagePath, Mode=OneWay}" Height="100" Width="150" Margin="5,5,5,5"/>
         </DataTemplate>
     </GridView.ItemTemplate>
 </GridView>

GridView for solid color wallpapers:

<GridView Name="SolidColorWallpaper"
          ItemsSource="{x:Bind ViewModel.SolidColorWallpaerCollection, Mode=OneWay}"
          IsItemClickEnabled="True"
          FlowDirection="LeftToRight"
          SelectionMode="Single"
          IsMultiSelectCheckBoxEnabled="False"
          ItemClick="SolidColorWallpaperCollection_ItemClick"
          Padding="5,0,5,0">
    <GridView.ItemsPanel>
        <ItemsPanelTemplate>
            <ItemsWrapGrid Orientation="Horizontal"/>
        </ItemsPanelTemplate>
    </GridView.ItemsPanel>
    <GridView.ItemTemplate>
        <DataTemplate x:DataType="Models:Wallpaper">
            <Rectangle Fill="{x:Bind Color}" Height="100" Width="150" Margin="5,5,5,5" />
        </DataTemplate>
    </GridView.ItemTemplate>
</GridView>

Wallpaper:

  public class Wallpaper
  {
      public string Color { get; set; }
      public string ImagePath { get; set; }
      public bool IsSolidColor { get; set; }
  }

Solution

  • You should try the AdvancedCollectionView from the CommunityToolkit.WinUI.Collections NuGet package:

    public class Wallpaper
    {
        public string Name { get; set; }
        public bool IsSolidColor { get; set; }
    }
    
    public partial class MainViewModel : ObservableObject
    {
        [ObservableProperty]
        private ObservableCollection<Wallpaper> _wallpapers = new();
    
        [ObservableProperty]
        private AdvancedCollectionView _wallpapersView = new();
    
        public MainViewModel()
        {
            Wallpapers.Add(new Wallpaper { Name = "Wallpaper 1", IsSolidColor = false });
            Wallpapers.Add(new Wallpaper { Name = "Solid Color 4", IsSolidColor = true });
            Wallpapers.Add(new Wallpaper { Name = "Wallpaper 3", IsSolidColor = false });
    
            Wallpapers.Add(new Wallpaper { Name = "Solid Color 1", IsSolidColor = true });
            Wallpapers.Add(new Wallpaper { Name = "Solid Color 2", IsSolidColor = true });
            Wallpapers.Add(new Wallpaper { Name = "Solid Color 3", IsSolidColor = true });
            Wallpapers.Add(new Wallpaper { Name = "Wallpaper 2", IsSolidColor = false });
            Wallpapers.Add(new Wallpaper { Name = "Solid Color 5", IsSolidColor = true });
    
            WallpapersView.Source = Wallpapers;
        }
    
        [RelayCommand]
        private void SwitchFilter()
        {
            if (WallpapersView.Filter is null)
            {
                WallpapersView.Filter = item => item is Wallpaper { IsSolidColor: true };
            }
            else
            {
                WallpapersView = new AdvancedCollectionView(Wallpapers);
            }
        }
    }
    

    ObservableObject and ObservableProperty come from the CommunityToolkit.Mvvm NuGet package but you can use the AdvancedCollectionView without them.