Build a Responsive Kanban Board Application in WPF using C# and MVVM 🚀

Are you looking for a practical WPF project to improve your C#, MVVM, and desktop application development skills? In this series, we will build a Responsive Kanban Board Application from scratch using WPF, C#, and MVVM architecture . This project is inspired by modern task management tools like Trello and helps you understand how real-world desktop applications are designed and developed. Why Build a Kanban Board in WPF? Many developers learn WPF concepts individually: Buttons TextBoxes Data Binding Commands Collections But when building a real application, you need to combine everything together. A Kanban Board project helps you learn: ✅ Real UI design ✅ MVVM architecture ✅ Dynamic data handling ✅ User interaction ✅ Drag & Drop functionality ✅ Command-based programming ✅ Reusable WPF components What You Will Build in This WPF Project We create a responsive Kanban Board where users can manage tasks visually. The application contains: 📌 Multiple ...

How to apply theme and color in wpf Metro window application

In this example i am using Prism,unity and MahApps make sure you are also using same otherwise you will not get PrismApplication,BindableBase and MetroWindow.

 MainWindow.xaml

 <metro:MetroWindow x:Class="WpfApplication.Views.MainWindow"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:local="clr-namespace:WpfApplication"
             mc:Ignorable="d"
             xmlns:metro="http://metro.mahapps.com/winfx/xaml/controls"
             xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
             Title="Welcome To Metro ui with Prism Unity">
     <metro:MetroWindow.RightWindowCommands>
         <metro:WindowCommands>
             <ComboBox ItemsSource="{Binding LstTheme}" SelectedItem="{Binding SelectedTheme}" Width="100" Background="Transparent" BorderBrush="Transparent">
                 <i:Interaction.Triggers>
                     <i:EventTrigger EventName="SelectionChanged">
                         <i:InvokeCommandAction Command="{Binding DataContext.ApplyThemeCommand,RelativeSource={RelativeSource AncestorType={x:Type ComboBox}}}"/>
                     </i:EventTrigger>
                 </i:Interaction.Triggers>
                 <ComboBox.ItemTemplate>
                     <DataTemplate>
                         <StackPanel Orientation="Horizontal">
                             <Ellipse Width="20" Height="20" Fill="{Binding Value}"/>
                             <TextBlock Text="{Binding Name}" Margin="5" VerticalAlignment="Center"/>
                         </StackPanel>
                     </DataTemplate>
                 </ComboBox.ItemTemplate>
             </ComboBox>
             <ComboBox ItemsSource="{Binding LstColor}" SelectedItem="{Binding SelectedColor}" Width="100" Background="Transparent" BorderBrush="Transparent">
                 <i:Interaction.Triggers>
                     <i:EventTrigger EventName="SelectionChanged">
                         <i:InvokeCommandAction Command="{Binding DataContext.ApplyColorCommand,RelativeSource={RelativeSource AncestorType={x:Type ComboBox}}}"/>
                     </i:EventTrigger>
                 </i:Interaction.Triggers>
                 <ComboBox.ItemTemplate>
                     <DataTemplate>
                         <StackPanel Orientation="Horizontal">
                             <Ellipse Width="20" Height="20" Fill="{Binding Value}"/>
                             <TextBlock Text="{Binding Name}" Margin="5" VerticalAlignment="Center"/>
                         </StackPanel>
                     </DataTemplate>
                 </ComboBox.ItemTemplate>
             </ComboBox>
         </metro:WindowCommands>


     </metro:MetroWindow.RightWindowCommands>
     <StackPanel Orientation="Vertical" HorizontalAlignment="Center" VerticalAlignment="Center">
         <!--here i used DynamicResource for Foreground/Background because i want to dynamically change the color-->
         <TextBlock Height="30" Width="200" Text="This is TextBlock" Margin="5" Foreground="{DynamicResource AccentBaseColorBrush}"/>
         <Button Content="This is Button" HorizontalAlignment="Left" Width="200" Background="{DynamicResource AccentBaseColorBrush}"/>
     </StackPanel>
 </metro:MetroWindow>

 MainWindow.xaml.cs

   public partial class MainWindow : MetroWindow
     {
         public MainWindow()
         {
             InitializeComponent();
             DataContext = new MainWindowViewModel();
         }

     }


 MainWindowViewModel.cs

 public class MainWindowViewModel : BindableBase
    {

        public MainWindowViewModel()
        {
            ApplyThemeCommand = new DelegateCommand(ApplyTheme);
            ApplyColorCommand = new DelegateCommand(ApplyColor);

            _lstTheme = new ObservableCollection<NameValue>()
            {
                new NameValue() {Name = "Light", Value = "White"},
                new NameValue() {Name = "Dark", Value = "Black"}
            };

            SelectedTheme = LstTheme[0];

            _lstColor = new ObservableCollection<NameValue>()
            {
                new NameValue() {Name = "blue", Value = "#2196F3"},
                new NameValue() {Name = "red", Value = "#e52400"},
                new NameValue() {Name = "green", Value = "#60a917"},

                new NameValue() {Name = "purple", Value = "#800080"},
                new NameValue() {Name = "orange", Value = "#fa6800"}

            };

            SelectedColor = _lstColor[0];
        }

        private void ApplyColor()
        {
            ApplyThemeColor();
        }

        private void ApplyTheme()
        {
            ApplyThemeColor();
        }
        private void ApplyThemeColor()
        {
            try
            {
                var accent = SelectedColor.Name ?? LstColor[0].Name;
                var theme = SelectedTheme.Name ?? LstTheme[0].Name;
                Accent newAccent = ThemeManager.GetAccent(accent);
                AppTheme newTheme = ThemeManager.GetAppTheme("Base" + theme);
                ThemeManager.ChangeAppStyle(Application.Current, newAccent, newTheme);
            }
            catch (System.Exception ex)
            {


            }
        }


        private ObservableCollection<NameValue> _lstTheme;

        public ObservableCollection<NameValue> LstTheme
        {
            get { return _lstTheme; }
            set { SetProperty(ref _lstTheme, value); }
        }


        private ObservableCollection<NameValue> _lstColor;

        public ObservableCollection<NameValue> LstColor
        {
            get { return _lstColor; }
            set { SetProperty(ref _lstColor, value); }
        }
        private NameValue _selectedColor;

        public NameValue SelectedColor
        {
            get { return _selectedColor; }
            set { SetProperty(ref _selectedColor, value); }
        }

        private NameValue _selectedTheme;

        public NameValue SelectedTheme
        {
            get { return _selectedTheme; }
            set { SetProperty(ref _selectedTheme, value); }
        }

        public ICommand ApplyThemeCommand { get; set; }
        public ICommand ApplyColorCommand { get; set; }

    }

 NameValue.cs

  public class NameValue : BindableBase
     {

         private string _name;

         public string Name
         {
             get { return _name; }
             set { SetProperty(ref _name, value); }
         }
         private string _value;

         public string Value
         {
             get { return _value; }
             set { SetProperty(ref _value, value); }
         }

     }


 App.xaml

 <prism:PrismApplication x:Class="WpfApplication.App"
              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
              xmlns:local="clr-namespace:WpfApplication"
              xmlns:prism="http://prismlibrary.com/">
     <Application.Resources>
         <ResourceDictionary>
             <ResourceDictionary.MergedDictionaries>

                 <!-- MahApps.Metro resource dictionaries. Make sure that all file names are Case Sensitive! -->
                 <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.xaml"/>

                 <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Fonts.xaml"/>
                 <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Colors.xaml"/>

                 <!-- Accent and AppTheme setting -->
                 <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/Blue.xaml" />
                 <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/BaseLight.xaml" />
             </ResourceDictionary.MergedDictionaries>
         </ResourceDictionary>
     </Application.Resources>
 </prism:PrismApplication>

 App.xaml.cs

  public partial class App : PrismApplication
     {
         IUnityContainer _container;
         protected override Window CreateShell()
         {
             return _container.Resolve<MainWindow>();
         }
         protected override void RegisterTypes(IContainerRegistry containerRegistry)
         {
             _container = containerRegistry.GetContainer();
         }
     }




Dark themes

Light theme






Comments

Popular posts from this blog

Filter DataGrid and ListView in wpf using ICollectionView

Pagination of DataGrid in WPF using MVVM

How to Create TabControl using Prism Region