自动从 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 会将新游戏显示为新行。
这里假设一个用户正在添加和观看游戏。
在其他用户可以插入新游戏并且您希望看到它出现的情况下,简单的解决方案是每隔几分钟轮询一次数据库。
如果您有很多用户和大量数据更改,那是不切实际的,但这看起来不像是那种要求。
我正在处理在 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 会将新游戏显示为新行。
这里假设一个用户正在添加和观看游戏。
在其他用户可以插入新游戏并且您希望看到它出现的情况下,简单的解决方案是每隔几分钟轮询一次数据库。
如果您有很多用户和大量数据更改,那是不切实际的,但这看起来不像是那种要求。