Understanding Commands in WPF: A Cleaner Alternative to Button Click Events

Many WPF developers start by using Button Click events for handling user actions. At first, this seems simple and straightforward. But very soon, the code-behind file becomes huge , and maintaining it turns into a challenge. One big problem arises: when the logic changes, the button does not enable or disable automatically , and testing button click logic becomes very difficult. So the big question is: Is there a better way to handle button actions in WPF? The answer is Commands . In this post, we’ll learn how to use Commands in WPF with a simple, practical example. We’ll cover: What a Command is How it works Why using Commands is better than Click events How buttons can automatically enable or disable based on conditions What is a Command in WPF? In WPF, a Command acts as a middle layer between the UI and your logic. Instead of the button directly calling a method, it triggers a Command , and the Command decides: What code should run Whether the button s...

How to save data from datagrid to database in C# WPF?

DataGridEx.xaml

<Window x:Class="PrismApp.Views.DataGridEx"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:prism="http://prismlibrary.com/"
             prism:ViewModelLocator.AutoWireViewModel="True">
    <Grid>
        <DataGrid ItemsSource="{Binding LstEmployees}"
                  AutoGenerateColumns="False" CanUserAddRows="False" >
            <DataGrid.Columns>
                <DataGridTextColumn Header="Employee Id" Binding="{Binding EmpId}" IsReadOnly="True"/>
                <DataGridTextColumn Header="Employee Name" Binding="{Binding EmpName,UpdateSourceTrigger=PropertyChanged}" />
                <DataGridTextColumn Header="Job Title" Binding="{Binding JobTitle,UpdateSourceTrigger=PropertyChanged}"/>
                <DataGridTextColumn Header="Experience" Binding="{Binding Experience,UpdateSourceTrigger=PropertyChanged}"/>
                <DataGridTextColumn Header="Salary" Binding="{Binding Salary,UpdateSourceTrigger=PropertyChanged}"/>
                <DataGridTemplateColumn Header="Update" Width="*">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <Button Content="P" FontFamily="Wingdings 2" FontWeight="ExtraBold"
                                    Background="Transparent" BorderThickness="0" FontSize="30"
                                    Command="{Binding DataContext.UpdateCommand,RelativeSource={RelativeSource AncestorType=DataGrid}}"
                                    CommandParameter="{Binding}">
                                <Button.Style>
                                    <Style BasedOn="{StaticResource {x:Type Button}}"  TargetType="Button">
                                        <Setter Property="Foreground" Value="Gray"/>
                                        <Setter Property="IsEnabled" Value="False"/>
                                        <Style.Triggers>
                                            <DataTrigger Binding="{Binding IsValueChanged,UpdateSourceTrigger=PropertyChanged}" Value="true">
                                                <Setter Property="Foreground" Value="Green"/>
                                                <Setter Property="IsEnabled" Value="True"/>

                                            </DataTrigger>
                                        </Style.Triggers>
                                    </Style>
                                </Button.Style>
                            </Button>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
            </DataGrid.Columns>
        </DataGrid>

    </Grid>
</Window>
DataGridEx.xaml.cs

 public partial class DataGridEx : Window
    {
        public DataGridEx()
        {
            InitializeComponent();
        }
  }


DataGridExViewModel.cs

 public class DataGridExViewModel : BindableBase
    {
        public DataGridExViewModel()
        {

            LoadEmployees();
            LstEmployees.Select(x =>
            {
                x.IsValueChanged = false;
                return x;
            }).ToList();
        }

        private ObservableCollection<Employees> _lstEmployees = new ObservableCollection<Employees>();
        public ObservableCollection<Employees> LstEmployees
        {
            get { return _lstEmployees; }
            set { SetProperty(ref _lstEmployees, value); }
        }
        private DelegateCommand<Employees> _updateCommand;
        public DelegateCommand<Employees> UpdateCommand =>
            _updateCommand ?? (_updateCommand = new DelegateCommand<Employees>(Update));

        void Update(Employees employee)
        {
            using(var sqlite = new SqliteOperation(@"\Projects\emp.db"))
            {
                sqlite.Update(employee);
            }
            LstEmployees.Select(x =>
            {
                if(x.EmpId == employee.EmpId)
                    x.IsValueChanged = false;
                return x;
            }).ToList();
        }
        private void LoadEmployees()
        {
            using(var sqlite = new SqliteOperation(@"\Projects\emp.db"))
            {
                LstEmployees.AddRange(sqlite.Get());
            }
        }


    }

SqliteOperation.cs

 public class SqliteOperation : IDisposable
    {
        public void Dispose()
        {
            GC.SuppressFinalize(this);
        }
        private readonly SQLiteConnection connection;
        public SqliteOperation(string connectionString)
        {
            connection = new SQLiteConnection(connectionString);
            connection.CreateTable<Employees>();
        }
        public void Add(Employees employee)
        {
            connection.Insert(employee);
        }
        public void Update(Employees employee)
        {
            connection.Update(employee);
        }
        public List<Employees> Get()
        {
            return connection.Table<Employees>().ToList();
        }
    }

Employees.cs

 public class Employees : BindableBase
    {
        private int _empId;

        [AutoIncrement, PrimaryKey]
        public int EmpId
        {
            get { return _empId; }
            set { SetProperty(ref _empId, value); }
        }
        private string _empName;
        [NotNull]
        public string EmpName
        {
            get { return _empName; }
            set
           {
                if(_empName != value)
                    IsValueChanged = true;
                SetProperty(ref _empName, value);
            }
        }
        private string _jobTitle;
        [NotNull]
        public string JobTitle
        {
            get { return _jobTitle; }
            set
            {
                if(_jobTitle != value)
                    IsValueChanged = true;
                SetProperty(ref _jobTitle, value);
            }
        }
        private string _experience;
        [NotNull]
        public string Experience
        {
            get { return _experience; }
            set
            {
                if(_experience != value)
                    IsValueChanged = true;
                SetProperty(ref _experience, value);
            }
        }
        private double _salary;
        [NotNull]
        public double Salary
        {
            get { return _salary; }
            set
            {
                if(_salary != value)
                    IsValueChanged = true;
                SetProperty(ref _salary, value);
            }
        }
        private bool _isValueChanged;
        [Ignore]
        public bool IsValueChanged
        {
            get { return _isValueChanged; }
            set { SetProperty(ref _isValueChanged, value); }
        }
    }


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