简体   繁体   中英

DataGrid doesn't refresh after adding new data from another view WPF C#

My RoomGrid doesn't refresh it's elements when an element is added from another View ( ReservationView ) but it's actually added to the databse,is there any possibility to refresh it automaticly while declaring my Rooms as DbSet<Room> not as ObservableCollection<Room> on DatabaseContext ?

If there is a possibily then how can I do that ?

If not then how can I implement ObservableCollection<Room> on my solution without rewritng the source code from zero ? (What are exactly the changes required to the source code ?)

(I'm working with MVVM design pattern,Linq,Entity Framework)

the source code of my DatabaseContext.cs :

using Fondok.Models;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration.Conventions;
using System.Data.SQLite;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Fondok.Context
{
    class DatabaseContext : DbContext
    {
        public DatabaseContext() :
            base(new SQLiteConnection()
            {
                ConnectionString = new SQLiteConnectionStringBuilder()
                {
                    DataSource = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\fondok.db",
                    ForeignKeys = true
                }.ConnectionString
            }, true)
        {
        }




        public DbSet<Client> Clients { get; set; }
        public DbSet<Room> Rooms { get; set; }
        public DbSet<Employee> Employees { get; set; }
        public DbSet<Form> Forms { get; set; }
        public DbSet<Reservation> Reservations { get; set; }

        public DbSet<Invoice> Invoices { get; set; }
    }

}

the source code of my RoomViewModel.cs :

using Fondok.Models;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using Fondok.Views.Windows;
using Fondok.Context;
using System.Data.Entity;
using System.Linq;
using System.Windows.Input;
using Fondok.Commands;
using System;
using System.Windows;
using System.Collections.Generic;
using System.Windows.Data;

namespace Fondok.ViewModels
{
    // ISIL 2016/2017 -------------------------------------------
    // RoomViewModel Class
    class RoomViewModel : INotifyPropertyChanged, IDataErrorInfo
    {

        //Constructor Null FirstTime
        public RoomViewModel() : this(null) { }
        // Constructor With Param Of The Model
        public RoomViewModel(Room Room)
        {

            // Add Room To Edit
            EditRoom = Room;

            //Validate Property
            IsValidProperty = false;

            //Make Properties With Fields Values
            RoomNumber = EditRoom.RoomNumber;
            RoomFloor = EditRoom.RoomFloor;
            RoomType = EditRoom.RoomType;
            RoomCapacity = EditRoom.RoomCapacity;
            RoomStatus = EditRoom.RoomStatus;
            RoomPrice = EditRoom.RoomPrice;

        }


        //IsValidProperty For Validation
        private bool _IsValidProperty;
        public bool IsValidProperty
        {
            get
            {
                return _IsValidProperty;
            }
            set
            {
                if (_IsValidProperty != value)
                {
                    _IsValidProperty = value;
                    NotifyPropertyChanged("IsValidProperty");
                }
            }
        }

        // Implementation Of IDataErrorInfo For Validation
        public string Error
        {
            get
            {
                return string.Empty;
            }
        }

        // RoomNumber Property
        private int _RoomNumber;
        public int RoomNumber
        {
            get
            {
                return _RoomNumber;
            }
            set
            {
                if (_RoomNumber != value)
                {
                    _RoomNumber = value;
                    EditRoom.RoomNumber = _RoomNumber;
                    NotifyPropertyChanged("RoomNumber");
                }
            }
        }

        // RoomFloor Property
        private int _RoomFloor;
        public int RoomFloor
        {
            get
            {
                return _RoomFloor;
            }
            set
            {
                if (_RoomFloor != value)
                {
                    _RoomFloor = value;

                    EditRoom.RoomFloor = _RoomFloor;

                    NotifyPropertyChanged("RoomFloor");

                }
            }
        }

        // RoomType Property
        private string _RoomType;
        public string RoomType
        {
            get
            {
                return _RoomType;
            }
            set
            {
                if (_RoomType != value)
                {
                    _RoomType = value;

                    EditRoom.RoomType = _RoomType;

                    NotifyPropertyChanged("RoomType");
                }
            }
        }

        // RoomCapacity Property
        private int _RoomCapacity;
        public int RoomCapacity
        {
            get
            {
                return _RoomCapacity;
            }
            set
            {
                if (_RoomCapacity != value)
                {
                    _RoomCapacity = value;

                    EditRoom.RoomCapacity = _RoomCapacity;

                    NotifyPropertyChanged("RoomCapacity");

                }
            }
        }

        // RoomStatus Property
        private string _RoomStatus;
        public string RoomStatus
        {
            get
            {
                return _RoomStatus;
            }
            set
            {
                if (_RoomStatus != value)
                {
                    _RoomStatus = value;

                    EditRoom.RoomStatus = _RoomStatus;

                    NotifyPropertyChanged("RoomStatus");
                }
            }
        }

        // RoomPrice Property
        private double _RoomPrice;
        public double RoomPrice
        {
            get
            {
                return _RoomPrice;
            }
            set
            {
                if (_RoomPrice != value)
                {
                    _RoomPrice = value;

                    EditRoom.RoomPrice = _RoomPrice;

                    NotifyPropertyChanged("RoomPrice");
                }
            }
        }

        // Add Conditions & Error Messages
        public string this[string columnName]
        {
            get
            {
                string FillRequired = "Please Fill The Field";
                switch (columnName)
                {
                    case "RoomNumber":
                        if (RoomNumber <= 0 || RoomNumber > 9999) return FillRequired;
                        break;
                    case "RoomFloor":
                        if (RoomFloor <= 0 || RoomFloor > 99) return FillRequired;
                        break;
                    case "RoomCapacity":
                        if (RoomCapacity <= 0 || RoomCapacity > 11) return FillRequired;
                        break;
                    case "RoomPrice":
                        if (RoomPrice <= 0 || RoomPrice > 999999) return FillRequired;
                        break;

                }
                return string.Empty;
            }
        }

        // Edit Room Property
        private Room _editRoom;
        public Room EditRoom
        {
            get
            {
                return _editRoom;
            }
            set
            {
                _editRoom = value;

                NotifyPropertyChanged("EditRoom");
            }
        }

        // RoomWindow Run() Method
        public bool Run()
        {
            RoomWindow window = new RoomWindow();

            window.DataContext = this;

            if (window.ShowDialog() == true) { return true; }
            return false;
        }

        // MVVM NotifyPropertyChanged Implementation
        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }


    // ISIL 2016/2017 -------------------------------------------
    // RoomDataInteraction Class Create, Read, Update, Delete
    class RoomDataInteraction
    {
        // Loading Data From DB 
        DatabaseContext db = new DatabaseContext();

        // RoomDataInteraction Constructor
        public RoomDataInteraction(DatabaseContext _db)
        {
            db = _db;
            db.Rooms.Load();

        }
        // Insert Data From To BindingList
        public System.ComponentModel.BindingList<Room> GetAllRooms()
        {
            return db.Rooms.Local.ToBindingList();
        }

        // Adding Method
        public void AddRoom(Room Room)
        {
            db.Rooms.Add(Room);
            db.SaveChanges();
        }

        // Get Room Method
        public Room GetRoom(int id)
        {
            return db.Rooms.Where(get => get.RoomID.Equals(id)).First();
        }

        // Update Room Method FirstTime
        public void UpdateRoom(
            int RoomID,
            int RoomNumber,
            int RoomFloor,
            string RoomType,
            int RoomCapacity,
            string RoomStatus,
            double RoomPrice
            )
        {
            Room Room = GetRoom(RoomID);
            Room.RoomNumber = RoomNumber;
            Room.RoomFloor = RoomFloor;
            Room.RoomType = RoomType;
            Room.RoomCapacity = RoomCapacity;
            Room.RoomStatus = RoomStatus;
            Room.RoomPrice = RoomPrice;

            db.SaveChanges();
        }
        // Update RoomStatus (getReserved) Amine Modification
        public void UpdateRoomStatus(
        int RoomNumber,
        string RoomStatus  )
        {
            Room Room = GetRoom(RoomNumber);

            Room.RoomStatus = RoomStatus;

            db.SaveChanges();

        }


        // Update Room Method After Insert
        public void UpdateRoom(Room update)
        {
            UpdateRoom(
                update.RoomID,
                update.RoomNumber,
                update.RoomFloor,
                update.RoomType,
                update.RoomCapacity,
                update.RoomStatus,
                update.RoomPrice
                );
        }


        // Delete Room Method
        public void DeleteRoom(int id)
        {
            db.Rooms.Remove(GetRoom(id));
            db.SaveChanges();
        }
    }


    // ISIL 2016/2017 -------------------------------------------
    // RoomBox Class
    class RoomBox : INotifyPropertyChanged
    {
        private RoomDataInteraction box;
        private DatabaseContext db;
        private BindingList<Room> _Rooms;

        // Rooms BindingList Property
        public BindingList<Room> Rooms
        {
            get
            {
                return _Rooms;
            }
            set
            {
                _Rooms = value;
                NotifyPropertyChanged("Rooms");
            }
        }

        // SelectedRoom Property
        private Room _selectedRoom;
        public Room SelectedRoom
        {
            get
            {
                return _selectedRoom;
            }
            set
            {
                _selectedRoom = value;
                NotifyPropertyChanged("SelectedRoom");
            }
        }

        // RoomBox Constructor
        public RoomBox()
        {
            db = new DatabaseContext();
            box = new RoomDataInteraction(db);
            Rooms = box.GetAllRooms();
            deleteCommand = new DelegateCommand(DeleteRoom);
            updateCommand = new DelegateCommand(UpdateRoom);
            createCommand = new DelegateCommand(CreateRoom);
        }

        // Check if Room Selected?
        public bool IsSelected()
        {
            return SelectedRoom != null;
        }

        // Implementation Of DeleteCommand Property
        private ICommand deleteCommand;
        public ICommand DeleteCommand
        {
            get
            {
                return deleteCommand;
            }
        }

        // Delete the Selected Room Method & Refresh Rooms Binding :)
        public void DeleteRoom()
        {
            if (!IsSelected())
            {
                return;
            }
            box.DeleteRoom(SelectedRoom.RoomID);
            Rooms.ResetBindings();
        }

        // Implementation Of UpdateCommand Property
        private DelegateCommand updateCommand;
        public ICommand UpdateCommand
        {
            get
            {
                return updateCommand;
            }
        }

        // Update the Selected Room Method & Refresh Rooms Binding :)
        public void UpdateRoom()
        {
            // Check If Selected?
            if (!IsSelected())
            {
                return;
            }

            // Create View Model With Selected Room To Edit
            RoomViewModel vm = new RoomViewModel(SelectedRoom);

            // Run The Room Window And Add Selected Room To Edit & Refresh Binding
            if (vm.Run())
            {
                box.UpdateRoom(SelectedRoom);
                Rooms.ResetBindings();
            }
        }

        // Implementation Of CreateCommand Property
        private DelegateCommand createCommand;
        public ICommand CreateCommand
        {
            get
            {
                return createCommand;
            }
        }

        //  Create Room Method & Refresh Rooms Binding :)
        public void CreateRoom()
        {
            Room create = new Room();

            RoomViewModel vm = new RoomViewModel(create);

            // Run The Room Window To Create Room & Refresh Binding
            if (vm.Run())
            {
                box.AddRoom(create);

                Rooms.ResetBindings();
            }
        }

        // MVVM NotifyPropertyChanged Implementation
        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

The source code of my RoomView.xaml :

<UserControl
  x:Class="Fondok.Views.RoomView"
  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:local="clr-namespace:Fondok.Views"
  xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
  xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  xmlns:prism="http://prismlibrary.com/"
  xmlns:vm="clr-namespace:Fondok.ViewModels"
  prism:ViewModelLocator.AutoWireViewModel="True"
  Background="{DynamicResource MaterialDesignPaper}"
  FontFamily="{DynamicResource MaterialDesignFont}"
  Loaded="RoomViewLoaded"
  TextElement.FontSize="18"
  TextElement.FontWeight="Regular"
  TextElement.Foreground="{DynamicResource MaterialDesignBody}"
  TextOptions.TextFormattingMode="Ideal"
  TextOptions.TextRenderingMode="Auto"
  mc:Ignorable="d">

  <UserControl.DataContext>
    <vm:RoomBox />
  </UserControl.DataContext>

  <Grid>
    <Grid.RowDefinitions>
      <RowDefinition Height="*" />
      <RowDefinition Height="64" />
    </Grid.RowDefinitions>
    <Grid Grid.Row="0">
      <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="auto" />
        <ColumnDefinition Width="auto" />
        <ColumnDefinition Width="auto" />
      </Grid.ColumnDefinitions>
    </Grid>
    <Grid Grid.Row="0">
      <DataGrid
        x:Name="RoomsGrid"
        Grid.Row="0"
        AutoGenerateColumns="True"
        Background="{Binding MaterialDesignBackground}"
        BorderBrush="{x:Null}"
        CanUserAddRows="True"
        CanUserResizeRows="False"
        ColumnWidth="*"
        FontSize="16"
        IsReadOnly="True"
        ItemsSource="{Binding Rooms, IsAsync=True, Mode=TwoWay}"
        SelectedItem="{Binding SelectedRoom}"
        SelectionMode="Single">
        <DataGrid.CellStyle>
          <Style TargetType="DataGridCell">
            <Setter Property="BorderThickness" Value="0" />
            <Setter Property="FocusVisualStyle" Value="{x:Null}" />
            <Setter Property="Padding" Value="16" />
            <Setter Property="Template">
              <Setter.Value>
                <ControlTemplate TargetType="{x:Type DataGridCell}">
                  <Border
                    Padding="{TemplateBinding Padding}"
                    Background="{TemplateBinding Background}"
                    BorderBrush="{TemplateBinding BorderBrush}"
                    BorderThickness="{TemplateBinding BorderThickness}"
                    SnapsToDevicePixels="True">
                    <ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
                  </Border>
                </ControlTemplate>
              </Setter.Value>
            </Setter>
            <Style.Triggers>
              <Trigger Property="IsSelected" Value="True">
                <Setter Property="Background" Value="{DynamicResource PrimaryHueLightBrush}" />
                <Setter Property="Foreground" Value="White" />
              </Trigger>
            </Style.Triggers>
          </Style>
        </DataGrid.CellStyle>

      </DataGrid>
    </Grid>
    <Grid Grid.Row="2">
      <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="*" />
      </Grid.ColumnDefinitions>
      <Button
        Grid.Row="2"
        Grid.Column="0"
        Height="36"
        Margin="16,0,8,0"
        Command="{Binding UpdateCommand}"
        Content="Edit Room"
        FontSize="18"
        FontWeight="Bold"
        Foreground="White"
        IsEnabled="{Binding ElementName=RoomsGrid, Path=SelectedItems.Count}"
        Style="{StaticResource MaterialDesignRaisedButton}" />
      <Button
        Grid.Row="2"
        Grid.Column="1"
        Height="36"
        Margin="8"
        Command="{Binding DeleteCommand}"
        Content="Remove Room"
        FontSize="18"
        FontWeight="Bold"
        Foreground="White"
        IsEnabled="{Binding ElementName=RoomsGrid, Path=SelectedItems.Count}"
        Style="{StaticResource MaterialDesignRaisedButton}" />
      <Button
        Grid.Row="2"
        Grid.Column="2"
        Height="36"
        Margin="8,0,16,0"
        Command="{Binding CreateCommand}"
        Content="Add Room"
        FontSize="18"
        FontWeight="Bold"
        Foreground="White"
        Style="{StaticResource MaterialDesignRaisedAccentButton}" />


    </Grid>
  </Grid>
</UserControl>

and the source code of my RoomView.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace Fondok.Views
{
    /// <summary>
    /// Interaction logic for RoomView.xaml
    /// </summary>
    public partial class RoomView : UserControl
    {
        public RoomView()
        {
            InitializeComponent();
        }

        void RoomViewLoaded(object sender, RoutedEventArgs e)
        {
            RoomsGrid.UpdateLayout();
            RoomsGrid.Items.Refresh();

        }
    }
}

for the ObservableCollection, you can add like this:

    public ObservableCollection<Room> Rooms
    {
        get { return _rooms; }
        set
        {
            _rooms = value;
            OnPropertyChanged("Rooms");
        }
    }

for the refresh after adding, i don't understand clearly

Is there any possibility to refresh it automaticly while declaring my Rooms as DbSet not as ObservableCollection on DatabaseContext?

No, at least not without explicitly update the binding target and that's nothing you want to do in the context of a view model that doesn't know anything about the binding.

If not then how can I implement ObservableCollection on my solution without rewritng the source code from zero ?

Add or remove from the ObservableCollection whenever you add or remove from the database:

class RoomBox : INotifyPropertyChanged
{
    private RoomDataInteraction box;
    private DatabaseContext db;
    private ObservableCollection<Room> _Rooms;

    // Rooms BindingList Property
    public ObservableCollection<Room> Rooms
    {
        get
        {
            return _Rooms;
        }
        set
        {
            _Rooms = value;
            NotifyPropertyChanged("Rooms");
        }
    }

    // SelectedRoom Property
    private Room _selectedRoom;
    public Room SelectedRoom
    {
        get
        {
            return _selectedRoom;
        }
        set
        {
            _selectedRoom = value;
            NotifyPropertyChanged("SelectedRoom");
        }
    }

    // RoomBox Constructor
    public RoomBox()
    {
        db = new DatabaseContext();
        box = new RoomDataInteraction(db);
        Rooms = new ObservableCollection<Room>(box.GetAllRooms());
        deleteCommand = new DelegateCommand(DeleteRoom);
        updateCommand = new DelegateCommand(UpdateRoom);
        createCommand = new DelegateCommand(CreateRoom);
    }

    // Check if Room Selected?
    public bool IsSelected()
    {
        return SelectedRoom != null;
    }

    // Implementation Of DeleteCommand Property
    private ICommand deleteCommand;
    public ICommand DeleteCommand
    {
        get
        {
            return deleteCommand;
        }
    }

    // Delete the Selected Room Method & Refresh Rooms Binding :)
    public void DeleteRoom()
    {
        if (!IsSelected())
        {
            return;
        }
        box.DeleteRoom(SelectedRoom.RoomID);
        Rooms.Delete(SelectedRoom);
    }

    // Implementation Of UpdateCommand Property
    private DelegateCommand updateCommand;
    public ICommand UpdateCommand
    {
        get
        {
            return updateCommand;
        }
    }

    // Update the Selected Room Method & Refresh Rooms Binding :)
    public void UpdateRoom()
    {
        // Check If Selected?
        if (!IsSelected())
        {
            return;
        }

        // Create View Model With Selected Room To Edit
        RoomViewModel vm = new RoomViewModel(SelectedRoom);

        // Run The Room Window And Add Selected Room To Edit & Refresh Binding
        if (vm.Run())
        {
            box.UpdateRoom(SelectedRoom);
        }
    }

    // Implementation Of CreateCommand Property
    private DelegateCommand createCommand;
    public ICommand CreateCommand
    {
        get
        {
            return createCommand;
        }
    }

    //  Create Room Method & Refresh Rooms Binding :)
    public void CreateRoom()
    {
        Room create = new Room();

        RoomViewModel vm = new RoomViewModel(create);

        // Run The Room Window To Create Room & Refresh Binding
        if (vm.Run())
        {
            box.AddRoom(create);
            Rooms.Add(create);
        }
    }

    // MVVM NotifyPropertyChanged Implementation
    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM