Lesson 21.4 - Completing the trading screen
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.ComponentModel; | |
using System.Linq; | |
using System.Text; | |
using System.Threading.Tasks; | |
namespace Engine | |
{ | |
public class InventoryItem : INotifyPropertyChanged | |
{ | |
private Item _details; | |
private int _quantity; | |
public Item Details | |
{ | |
get { return _details; } | |
set | |
{ | |
_details = value; | |
OnPropertyChanged("Details"); | |
} | |
} | |
public int Quantity | |
{ | |
get { return _quantity; } | |
set | |
{ | |
_quantity = value; | |
OnPropertyChanged("Quantity"); | |
OnPropertyChanged("Description"); | |
} | |
} | |
public int ItemID | |
{ | |
get { return Details.ID; } | |
} | |
public string Description | |
{ | |
get { return Quantity > 1 ? Details.NamePlural : Details.Name; } | |
} | |
public int Price | |
{ | |
get { return Details.Price; } | |
} | |
public InventoryItem(Item details, int quantity) | |
{ | |
Details = details; | |
Quantity = quantity; | |
} | |
public event PropertyChangedEventHandler PropertyChanged; | |
protected void OnPropertyChanged(string name) | |
{ | |
if(PropertyChanged != null) | |
{ | |
PropertyChanged(this, new PropertyChangedEventArgs(name)); | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.ComponentModel; | |
using System.Data; | |
using System.Drawing; | |
using System.Linq; | |
using System.Text; | |
using System.Threading.Tasks; | |
using System.Windows.Forms; | |
using Engine; | |
namespace SuperAdventure | |
{ | |
public partial class TradingScreen : Form | |
{ | |
private Player _currentPlayer; | |
// Commented out this property, because I chose to pass the player as a parameter in the constructor. | |
//public Player CurrentPlayer { get; set; } | |
public TradingScreen(Player player) | |
{ | |
_currentPlayer = player; | |
InitializeComponent(); | |
// Style, to display numeric column values | |
DataGridViewCellStyle rightAlignedCellStyle = new DataGridViewCellStyle(); | |
rightAlignedCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight; | |
// Populate the datagrid for the player's inventory | |
dgvMyItems.RowHeadersVisible = false; | |
dgvMyItems.AutoGenerateColumns = false; | |
// This hidden column holds the item ID, so we know which item to sell | |
dgvMyItems.Columns.Add(new DataGridViewTextBoxColumn | |
{ | |
DataPropertyName = "ItemID", | |
Visible = false | |
}); | |
dgvMyItems.Columns.Add(new DataGridViewTextBoxColumn | |
{ | |
HeaderText = "Name", | |
Width = 100, | |
DataPropertyName = "Description" | |
}); | |
dgvMyItems.Columns.Add(new DataGridViewTextBoxColumn | |
{ | |
HeaderText = "Qty", | |
Width = 30, | |
DefaultCellStyle = rightAlignedCellStyle, | |
DataPropertyName = "Quantity" | |
}); | |
dgvMyItems.Columns.Add(new DataGridViewTextBoxColumn | |
{ | |
HeaderText = "Price", | |
Width = 35, | |
DefaultCellStyle = rightAlignedCellStyle, | |
DataPropertyName = "Price" | |
}); | |
dgvMyItems.Columns.Add(new DataGridViewButtonColumn | |
{ | |
Text = "Sell 1", | |
UseColumnTextForButtonValue = true, | |
Width = 50, | |
DataPropertyName = "ItemID" | |
}); | |
// Bind the player's inventory to the datagridview | |
dgvMyItems.DataSource = _currentPlayer.Inventory; | |
// When the user clicks on a row, call this function | |
dgvMyItems.CellClick += dgvMyItems_CellClick; | |
// Populate the datagrid for the vendor's inventory | |
dgvVendorItems.RowHeadersVisible = false; | |
dgvVendorItems.AutoGenerateColumns = false; | |
// This hidden column holds the item ID, so we know which item to sell | |
dgvVendorItems.Columns.Add(new DataGridViewTextBoxColumn | |
{ | |
DataPropertyName = "ItemID", | |
Visible = false | |
}); | |
dgvVendorItems.Columns.Add(new DataGridViewTextBoxColumn | |
{ | |
HeaderText = "Name", | |
Width = 100, | |
DataPropertyName = "Description" | |
}); | |
dgvVendorItems.Columns.Add(new DataGridViewTextBoxColumn | |
{ | |
HeaderText = "Price", | |
Width = 35, | |
DefaultCellStyle = rightAlignedCellStyle, | |
DataPropertyName = "Price" | |
}); | |
dgvVendorItems.Columns.Add(new DataGridViewButtonColumn | |
{ | |
Text = "Buy 1", | |
UseColumnTextForButtonValue = true, | |
Width = 50, | |
DataPropertyName = "ItemID" | |
}); | |
// Bind the vendor's inventory to the datagridview | |
dgvVendorItems.DataSource = _currentPlayer.CurrentLocation.VendorWorkingHere.Inventory; | |
// When the user clicks on a row, call this function | |
dgvVendorItems.CellClick += dgvVendorItems_CellClick; | |
} | |
private void dgvMyItems_CellClick(object sender, DataGridViewCellEventArgs e) | |
{ | |
// The first column of a datagridview has a ColumnIndex = 0 | |
// This is known as a "zero-based" array/collection/list. | |
// You start counting with 0. | |
// | |
// The 5th column (ColumnIndex = 4) is the column with the button. | |
// So, if the player clicked the button column, we will sell an item from that row. | |
if(e.ColumnIndex == 4) | |
{ | |
// This gets the ID value of the item, from the hidden 1st column | |
// Remember, ColumnIndex = 0, for the first column | |
var itemID = dgvMyItems.Rows[e.RowIndex].Cells[0].Value; | |
// Get the Item object for the selected item row | |
Item itemBeingSold = World.ItemByID(Convert.ToInt32(itemID)); | |
if(itemBeingSold.Price == World.UNSELLABLE_ITEM_PRICE) | |
{ | |
MessageBox.Show("You cannot sell the " + itemBeingSold.Name); | |
} | |
else | |
{ | |
// Remove one of these items from the player's inventory | |
_currentPlayer.RemoveItemFromInventory(itemBeingSold); | |
// Give the player the gold for the item being sold. | |
_currentPlayer.Gold += itemBeingSold.Price; | |
} | |
} | |
} | |
private void dgvVendorItems_CellClick(object sender, DataGridViewCellEventArgs e) | |
{ | |
// The 4th column (ColumnIndex = 3) has the "Buy 1" button. | |
if(e.ColumnIndex == 3) | |
{ | |
// This gets the ID value of the item, from the hidden 1st column | |
var itemID = dgvVendorItems.Rows[e.RowIndex].Cells[0].Value; | |
// Get the Item object for the selected item row | |
Item itemBeingBought = World.ItemByID(Convert.ToInt32(itemID)); | |
// Check if the player has enough gold to buy the item | |
if(_currentPlayer.Gold >= itemBeingBought.Price) | |
{ | |
// Add one of the items to the player's inventory | |
_currentPlayer.AddItemToInventory(itemBeingBought); | |
// Remove the gold to pay for the item | |
_currentPlayer.Gold -= itemBeingBought.Price; | |
} | |
else | |
{ | |
MessageBox.Show("You do not have enough gold to buy the " + itemBeingBought.Name); | |
} | |
} | |
} | |
private void btnClose_Click(object sender, EventArgs e) | |
{ | |
Close(); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace SuperAdventure | |
{ | |
partial class TradingScreen | |
{ | |
/// <summary> | |
/// Required designer variable. | |
/// </summary> | |
private System.ComponentModel.IContainer components = null; | |
/// <summary> | |
/// Clean up any resources being used. | |
/// </summary> | |
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> | |
protected override void Dispose(bool disposing) | |
{ | |
if(disposing && (components != null)) | |
{ | |
components.Dispose(); | |
} | |
base.Dispose(disposing); | |
} | |
#region Windows Form Designer generated code | |
/// <summary> | |
/// Required method for Designer support - do not modify | |
/// the contents of this method with the code editor. | |
/// </summary> | |
private void InitializeComponent() | |
{ | |
this.dgvMyItems = new System.Windows.Forms.DataGridView(); | |
this.dgvVendorItems = new System.Windows.Forms.DataGridView(); | |
this.lblMyInventory = new System.Windows.Forms.Label(); | |
this.lblVendorInventory = new System.Windows.Forms.Label(); | |
this.btnClose = new System.Windows.Forms.Button(); | |
((System.ComponentModel.ISupportInitialize)(this.dgvMyItems)).BeginInit(); | |
((System.ComponentModel.ISupportInitialize)(this.dgvVendorItems)).BeginInit(); | |
this.SuspendLayout(); | |
// | |
// dgvMyItems | |
// | |
this.dgvMyItems.AllowUserToAddRows = false; | |
this.dgvMyItems.AllowUserToDeleteRows = false; | |
this.dgvMyItems.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; | |
this.dgvMyItems.Location = new System.Drawing.Point(13, 43); | |
this.dgvMyItems.Name = "dgvMyItems"; | |
this.dgvMyItems.ReadOnly = true; | |
this.dgvMyItems.Size = new System.Drawing.Size(240, 216); | |
this.dgvMyItems.TabIndex = 0; | |
// | |
// dgvVendorItems | |
// | |
this.dgvVendorItems.AllowUserToAddRows = false; | |
this.dgvVendorItems.AllowUserToDeleteRows = false; | |
this.dgvVendorItems.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; | |
this.dgvVendorItems.Location = new System.Drawing.Point(276, 43); | |
this.dgvVendorItems.Name = "dgvVendorItems"; | |
this.dgvVendorItems.ReadOnly = true; | |
this.dgvVendorItems.Size = new System.Drawing.Size(240, 216); | |
this.dgvVendorItems.TabIndex = 1; | |
// | |
// lblMyInventory | |
// | |
this.lblMyInventory.AutoSize = true; | |
this.lblMyInventory.Location = new System.Drawing.Point(99, 13); | |
this.lblMyInventory.Name = "lblMyInventory"; | |
this.lblMyInventory.Size = new System.Drawing.Size(68, 13); | |
this.lblMyInventory.TabIndex = 2; | |
this.lblMyInventory.Text = "My Inventory"; | |
// | |
// lblVendorInventory | |
// | |
this.lblVendorInventory.AutoSize = true; | |
this.lblVendorInventory.Location = new System.Drawing.Point(349, 13); | |
this.lblVendorInventory.Name = "lblVendorInventory"; | |
this.lblVendorInventory.Size = new System.Drawing.Size(95, 13); | |
this.lblVendorInventory.TabIndex = 3; | |
this.lblVendorInventory.Text = "Vendor\'s Inventory"; | |
// | |
// btnClose | |
// | |
this.btnClose.Location = new System.Drawing.Point(441, 274); | |
this.btnClose.Name = "btnClose"; | |
this.btnClose.Size = new System.Drawing.Size(75, 23); | |
this.btnClose.TabIndex = 4; | |
this.btnClose.Text = "Close"; | |
this.btnClose.UseVisualStyleBackColor = true; | |
this.btnClose.Click += new System.EventHandler(this.btnClose_Click); | |
// | |
// TradingScreen | |
// | |
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); | |
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; | |
this.ClientSize = new System.Drawing.Size(528, 310); | |
this.Controls.Add(this.btnClose); | |
this.Controls.Add(this.lblVendorInventory); | |
this.Controls.Add(this.lblMyInventory); | |
this.Controls.Add(this.dgvVendorItems); | |
this.Controls.Add(this.dgvMyItems); | |
this.Name = "TradingScreen"; | |
this.Text = "Trade"; | |
((System.ComponentModel.ISupportInitialize)(this.dgvMyItems)).EndInit(); | |
((System.ComponentModel.ISupportInitialize)(this.dgvVendorItems)).EndInit(); | |
this.ResumeLayout(false); | |
this.PerformLayout(); | |
} | |
#endregion | |
private System.Windows.Forms.DataGridView dgvMyItems; | |
private System.Windows.Forms.DataGridView dgvVendorItems; | |
private System.Windows.Forms.Label lblMyInventory; | |
private System.Windows.Forms.Label lblVendorInventory; | |
private System.Windows.Forms.Button btnClose; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections.Generic; | |
using System.ComponentModel; | |
using System.Linq; | |
namespace Engine | |
{ | |
public class Vendor : INotifyPropertyChanged | |
{ | |
public string Name { get; set; } | |
public BindingList<InventoryItem> Inventory { get; set; } | |
public Vendor(string name) | |
{ | |
Name = name; | |
Inventory = new BindingList<InventoryItem>(); | |
} | |
public void AddItemToInventory(Item itemToAdd, int quantity = 1) | |
{ | |
InventoryItem item = Inventory.SingleOrDefault(ii => ii.Details.ID == itemToAdd.ID); | |
if(item == null) | |
{ | |
// They didn't have the item, so add it to their inventory | |
Inventory.Add(new InventoryItem(itemToAdd, quantity)); | |
} | |
else | |
{ | |
// They have the item in their inventory, so increase the quantity | |
item.Quantity += quantity; | |
} | |
OnPropertyChanged("Inventory"); | |
} | |
public void RemoveItemFromInventory(Item itemToRemove, int quantity = 1) | |
{ | |
InventoryItem item = Inventory.SingleOrDefault(ii => ii.Details.ID == itemToRemove.ID); | |
if(item == null) | |
{ | |
// The item is not in the player's inventory, so ignore it. | |
// We might want to raise an error for this situation | |
} | |
else | |
{ | |
// They have the item in their inventory, so decrease the quantity | |
item.Quantity -= quantity; | |
// Don't allow negative quantities. | |
// We might want to raise an error for this situation | |
if(item.Quantity < 0) | |
{ | |
item.Quantity = 0; | |
} | |
// If the quantity is zero, remove the item from the list | |
if(item.Quantity == 0) | |
{ | |
Inventory.Remove(item); | |
} | |
// Notify the UI that the inventory has changed | |
OnPropertyChanged("Inventory"); | |
} | |
} | |
public event PropertyChangedEventHandler PropertyChanged; | |
private void OnPropertyChanged(string name) | |
{ | |
if(PropertyChanged != null) | |
{ | |
PropertyChanged(this, new PropertyChangedEventArgs(name)); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment