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

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

我正在处理在 WinForms 中设计的数据管理项目,而不是在 WPF(MVVM) 中重新设计它我正在使用 caliburn micro 显然是为了减少开发时间和灵活性,我遇到了一个我想将数据保存到数据库后立即刷新数据网格。这是我想要实现的目标的解释。

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):包含将数据添加到数据库的方法,为了简单起见,我在此示例中使用 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:包含从 GameData 获取数据的 ObservableCollection: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;
    }

这里我必须使用另一种方法来刷新 ObservableCollection,或者您可以说从数据库填充数据。我希望每当我添加任何数据时都应该自动完成。如何让它知道任何插入已完成。

为了参考,我分享了代码的最后一部分查看如下:

<!--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>

绑定工作正常,数据显示正常,但我希望它自动完成,请告诉我如何在不调用 RefreshGames 方法的情况下执行此操作。

提前谢谢你,如果这个问题很长,我很抱歉,但为了便于理解,我不得不把所有内容都说出来。

如果有人想分享他们对代码的评论,请分享。

当您在其中添加或删除条目时,observablecollection 会通知集合已更改。 你好像在说

public ObservableCollection<GameModel> AllGames

它与 AddNewGame 在同一个视图模型中。 如果你只是做

AllGames.Add(_gameModel);

在添加新游戏中。
然后您的 ListView 会将新游戏显示为新行。

这里假设一个用户正在添加和观看游戏。
在其他用户可以插入新游戏并且您希望看到它出现的情况下,简单的解决方案是每隔几分钟轮询一次数据库。
如果您有很多用户和大量数据更改,那是不切实际的,但这看起来不像是那种要求。