简体   繁体   English

从ObservableCollection中的数据库自动获取数据:WPF MVVM Caliburn Micro

[英]Automatically Get Data from DataBase in ObservableCollection : WPF MVVM Caliburn Micro

I am working on Data Management project which was designed in WinForms and not I am redesigning it in WPF(MVVM) I am using caliburn micro obviously to reduce development time and flexibility, I came across a huddle where I want to refresh the Data Grid as soon as I save the data into Database. 我正在研究WinForms中设计的数据管理项目,而不是在WPF(MVVM)中重新设计它,我显然是在使用caliburn micro来减少开发时间和灵活性,我遇到了一个杂乱的地方,我想刷新Data Grid作为一旦将数据保存到数据库中。 Here is explanation of what i want to achieve. 这是我要实现的解释。

1) GameModel : Contains 5 properties same as Database(GameID,GameName,GameCategory,GameCompany,GamePrice) 1)GameModel:包含与数据库相同的5个属性(GameID,GameName,GameCategory,GameCompany,GamePrice)

private string _gameID;
    private string _gameName;
    private string _gameComp;
    private string _gameCat;
    private int _gamePrice;

    public int GamePrice
    {
        get { return _gamePrice; }
        set
        {
            _gamePrice = value;
            NotifyOfPropertyChange(() => GamePrice);
        }
    }
    public string GameCat
    {
        get { return _gameCat; }
        set { _gameCat = value;
            NotifyOfPropertyChange(() => GameCat);
        }
    }
    public string GameComp
    {
        get { return _gameComp; }
        set { _gameComp = value;
            NotifyOfPropertyChange(() => GameComp);
        }
    }
    public string GameName
    {
        get { return _gameName; }
        set { _gameName = value;
            NotifyOfPropertyChange(() => GameName);
        }
    }
    public string GameID
    {
        get { return _gameID; }
        set { _gameID = value;
            NotifyOfPropertyChange(() => GameID);
        }
    }

2) GameData (DataAccessLayer): Contains method to Add data into database for sake of simplicity I am using DataTable for this example to get the answer. 2)GameData(DataAccessLayer):包含为简单起见向数据库添加数据的方法,我在此示例中使用DataTable来获取答案。

DataTable dt;
    public GameData()
    {
         dt = new DataTable("gameMaster");
        DataColumn col1 = new DataColumn("Srno", typeof(int));
        col1.AutoIncrement = true;
        col1.AutoIncrementSeed = 1;
        dt.Columns.Add(col1);
        dt.Columns.Add("GameID", typeof(string));
        dt.Columns.Add("GameName", typeof(string));
        dt.Columns.Add("GameComp", typeof(string));
        dt.Columns.Add("GameCat", typeof(string));
        dt.Columns.Add("GamePrice", typeof(int));
    }
    public bool AddNewGame(GameModel gm)
    {
        try
        {
            dt.Rows.Add(null, gm.GameID, gm.GameName, gm.GameComp, gm.GameCat, gm.GamePrice);
            return true;
        }
        catch (Exception e)
        {
            MessageBox.Show(e.ToString());
            return false;
        }
    }

    public List<GameModel> GetAllGames()
    {
        var gameList = new List<GameModel>();
        foreach(DataRow row in dt.Rows)
        {
            var game = new GameModel
            {
                GameID = row[1].ToString(),
                GameName = row[2].ToString(),
                GameComp= row[3].ToString(),
                GameCat= row[4].ToString(),
                GamePrice= (int)row[5],
            };
            gameList.Add(game);
        }
        return gameList;
    }

3) GameViewModel : Contains ObservableCollection which gets data from GameData : GetAllGames method. 3)GameViewModel:包含ObservableCollection,它从GameData:GetAllGames方法获取数据。

public GameData _gameData;
    public GameModel _gameModel;
    public GameViewModel()
    {
        GameCat.Add("Action");
        GameCat.Add("Arcade");
        GameCat.Add("Racing");
        GameCat.Add("Puzzle");
        GameCat.Add("Other");
        GameComp.Add("EA");
        GameComp.Add("EA Sports");
        GameComp.Add("Ubisoft");
        _gameData = new GameData();
        RefreshGames();
    }
    private ObservableCollection<GameModel> _allGames;
    public ObservableCollection<GameModel> AllGames
    {
        get { return _allGames; }
        set
        {
            _allGames = value;
            NotifyOfPropertyChange(() => AllGames);
        }
    }

    public void AddNewGame(string gameID, string gameName, string gameCat, string gameComp, int gamePrice)
    {
        _gameModel = new GameModel
        {
            GameID = gameID,
            GameName = gameName,
            GameCat = gameCat,
            GameComp = gameComp,
            GamePrice = gamePrice
        };

        if (_gameData.AddNewGame(_gameModel))
        {
            RefreshGames();
            MessageBox.Show("Game Added succesfully !");
        }
    }
    public void RefreshGames()
    {
        var obj = new ObservableCollection<GameModel>(_gameData.GetAllGames());
        AllGames = obj;
    }

Here I've to use another method in order to Refresh the ObservableCollection or you can say to populate data from DB. 在这里,我必须使用另一种方法来刷新ObservableCollection,或者可以说从数据库填充数据。 I want that whenever I add any data this should be automatically done. 我希望每当添加任何数据时都应自动完成此操作。 How to make it aware that any insertion was done. 如何使其知道已完成任何插入。

And for reference I am sharing the last portion of the code View as follow : 作为参考,我分享了代码View的最后一部分,如下所示:

<!--row1-->
    <TextBox Grid.Row="1" Grid.Column="1" materialDesign:HintAssist.Hint="GameID" materialDesign:HintAssist.IsFloating="True" x:Name="GameID"/>
    <!--row2-->
    <TextBox Grid.Row="2" Grid.Column="1" x:Name="GameName"/>
    <!--row3-->
    <ComboBox Grid.Row="3" Grid.Column="1" x:Name="GameCat" SelectedIndex="0"/>
    <!--row4-->
    <ComboBox Grid.Row="4" Grid.Column="1" x:Name="GameComp" SelectedIndex="0"/>
    <!--row5-->
    <TextBox Grid.Row="5" Grid.Column="1" x:Name="GamePrice"/>
    <!--row6-->
    <StackPanel Orientation="Horizontal" Grid.Row="6" Grid.Column="1" HorizontalAlignment="Right">
        <Button Content="Save" Width="60" x:Name="AddNewGame"/>
        <Button Content="Exit" Width="60" x:Name="Exit"/>
    </StackPanel>
    <!--row7-->
    <ListView Grid.Column="1" Grid.Row="7" ItemsSource="{Binding Path=AllGames}">
        <ListView.View>
            <GridView>
                <GridViewColumn Header="GameID" Width="Auto" DisplayMemberBinding="{Binding Path=GameID}"/>
                <GridViewColumn Header="GameName" Width="Auto" DisplayMemberBinding="{Binding Path=GameName}"/>
                <GridViewColumn Header="Category" Width="Auto" DisplayMemberBinding="{Binding Path=GameComp}"/>
                <GridViewColumn Header="Company" Width="Auto" DisplayMemberBinding="{Binding Path=GameCat}"/>
                <GridViewColumn Header="Price" Width="Auto" DisplayMemberBinding="{Binding Path=GamePrice}"/>
            </GridView>
        </ListView.View>
    </ListView>

Binding Works Fine, Data is showing fine but I want it to be done Automatically, Please let me know how can i do this without calling the RefreshGames method. 绑定工作正常,数据显示正常,但我希望它能自动完成,请让我知道如何在不调用RefreshGames方法的情况下进行此操作。

Thank you in Advance and sorry if this question is long but for sake of understanding i had to put everything. 在此先感谢您,如果这个问题很长,对不起,但是为了理解,我不得不放所有东西。

if any one wants to share their review on Code please share it. 如果有人想分享对Code的评论,请分享。

An observablecollection notifies collection changed when you add or remove entries from it. 当您从集合中添加或删除条目时,observablecollection会通知已更改的集合。 You seem to be talking about 你好像在说

public ObservableCollection<GameModel> AllGames

Which is in the same viewmodel as AddNewGame. 与AddNewGame在同一视图模型中。 If you just do 如果你只是做

AllGames.Add(_gameModel);

In AddNewGame. 在AddNewGame中。
Then your ListView will show the new game as a new row. 然后,您的ListView将新游戏显示为新行。

An assumption here is that the one user is adding and viewing the games. 这里的一个假设是,一个用户正在添加和查看游戏。
In a situation where other users could insert a new game and you want to see that appear then the simple solution is to poll the database every few minutes. 在其他用户可以插入新游戏并且您希望看到它出现的情况下,简单的解决方案是每隔几分钟轮询一次数据库。
That isn't practical if you have a LOT of users and a lot of data changing but this doesn't look like that sort of a requirement. 如果您有很多用户并且需要更改大量数据,那么这是不切实际的,但这似乎不是这种要求。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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