Question

I have two classes named Breed and PetType, these also are my tables in my sql server database

The Breed class is this:

public int Id { get; set; }
public string BreedName { get; set; }
public string Description { get; set; }
public int SortOrder { get; set; }
public bool StatusId { get; set; }
public int CreatedBy { get; set; }
public string CreatedByName { get; set; }
public int PetTypeId { get; set; } //Inner or left joined from PetTypes Table(stored procedure)
public string PetTypeName { get; set; }

The PetType class is this:

public int Id { get; set; }
public string PetTypeName { get; set; }
public string Description { get; set; }
public int SortOrder { get; set; }
public bool StatusId { get; set; }
public int CreatedBy { get; set; }
public string CreatedByName { get; set; }

then in my DataAccessLayer project,

    public List<Breed> RetrieveMany(Breed parameters)
    {
        var items = new List<Breed>();
        var command = new SqlCommand {CommandText = "SP_RetrieveBreeds", CommandType = CommandType.StoredProcedure};

        command.Parameters.AddWithValue("@Id", parameters.Id).Direction = ParameterDirection.Input;
        command.Parameters.AddWithValue("@Name", parameters.BreedName).Direction = ParameterDirection.Input;
        command.Parameters.AddWithValue("@PetTypeId", parameters.PetTypeId).Direction = ParameterDirection.Input;
        DataTable dt = SqlHelper.GetData(command);

        foreach (DataRow row in dt.Rows)
        {
            var item = new Breed();
            item.Id = Convert.ToInt32(row["Id"].ToString());
            item.PetTypeId = Convert.ToInt32(row["PetTypeId"].ToString());
            item.PetTypeName = (row["PetTypeName"]).ToString();
            item.BreedName =  row["BreedName"].ToString();
            item.Description =  row["Description"].ToString();
            item.SortOrder = Convert.ToInt32(row["SortOrder"].ToString());
            item.CreatedBy = Convert.ToInt32(row["CreatedById"].ToString());
            item.CreatedByName =  row["CreatedByName"].ToString();

            items.Add(item);
        }

        return items;
    }

Then i declare itemMgr as an object. put these items in a list of object

BreedDataAccess itemMgr =  new BreedDataAccess();

public void LoadGridview()
    {
        Breed BreedParam = RetrieveFilter(searchCrit); //gets all filter parameters for individual searching
        //this.itemMgr.EntityList = itemMgr.RetrieveMany(itemMgr.Parameters);


        List <Breed> listOfBreeds = new List<Breed>();

        listOfBreeds = DataAcessLayer.RetrieveMany(BreedParam); 

        this.dgvBreeds.AutoGenerateColumns = false;
        this.dgvBreeds.ItemSource = this.itemMgr.EntityList;
    }

This is what I tried for my mark up:

<Window x:Class="NeoClinic.WPFTryOut.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <DataGrid x:Name="dgvBreeds" HorizontalAlignment="Left" VerticalAlignment="Top" Height="319" Width="517"/>
</Grid>

I tried the code in windows form DataGridView and it worked just fine.
But I don't know how to do it in WPF.

Was it helpful?

Solution

I see that you're handling events, presumably in the code behind of the window / control. This creates a strong coupling between the UI elements and the logic that sits behind, which in turn makes testing a lot harder.

I would consider using the MVVM pattern and doing this sort of thing in the View Model. Using this approach you can reduce the coupling between UI (View) and the logic (View Model).

I've put together a very simple application (targeting .Net 4.5) to demonstrate binding a collection to the data grid and how to delete the selected row.

Here is the XAML:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow"
        Width="525"
        Height="350">
    <Grid>
        <StackPanel>
            <DataGrid ItemsSource="{Binding People}" SelectedItem="{Binding SelectedItem}" />
            <Button Command="{Binding DeleteCommand}">Delete Selected Row</Button>
        </StackPanel>
    </Grid>
</Window>

MainWindow.xaml.cs

using System;
using System.Windows;
using System.Windows.Input;

namespace WpfApplication1
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            DataContext = new MainViewModel();
        }
    }

Person.cs

using System;

namespace WpfApplication1
{
    public class Person
    {
        public string Forename { get; set; }

        public string Surname { get; set; }
    }
}

DelegateCommand.cs

using System;
using System.Windows;
using System.Windows.Input;

namespace WpfApplication1
{
    public class DelegateCommand : ICommand
    {
        private readonly Predicate<object> _canExecute;
        private readonly Action<object> _execute;

        public event EventHandler CanExecuteChanged;

        public DelegateCommand(Action<object> execute)
            : this(execute, null)
        {
        }

        public DelegateCommand(Action<object> execute,
                       Predicate<object> canExecute)
        {
            _execute = execute;
            _canExecute = canExecute;
        }

        public bool CanExecute(object parameter)
        {
            if (_canExecute == null)
            {
                return true;
            }
            return _canExecute(parameter);
        }

        public void Execute(object parameter)
        {
            _execute(parameter);
        }

        public void RaiseCanExecuteChanged()
        {
            if (CanExecuteChanged != null)
            {
                CanExecuteChanged(this, EventArgs.Empty);
            }
        }
    }
}

MainViewModel.cs

using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows.Input;

namespace WpfApplication1
{
    internal class MainViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        public MainViewModel()
        {
            People = new ObservableCollection<Person>();
            DeleteCommand = new DelegateCommand(x => DeleteSelectedItem(null));

            People.Add(new Person { Forename = "Bob", Surname = "Smith" });
            People.Add(new Person { Forename = "Alice", Surname = "Jones" });
        }

        private void DeleteSelectedItem(object obj)
        {
            People.Remove(SelectedItem);
            SelectedItem = null;
        }

        public ICommand DeleteCommand { get; set; }

        public ObservableCollection<Person> People { get; set; }

        private Person selectedItem;

        public Person SelectedItem
        {
            get { return selectedItem; }
            set
            {
                if (selectedItem == value)
                    return;

                selectedItem = value;
                OnPropertyChanged();
            }
        }

        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top