我有一个程序,用户可以选择"类"基于组合框的船舶。目前,所有统计数据和类都被硬编码到程序中。问题是我希望能够根据需要添加额外的船型。最好以简单的方式,我的朋友(几乎不知道代码),并添加船只(计划是我完成后,我将给他一份副本使用)。每艘船使用一个名称和3个统计数据。我目前的硬编码是 -
private void cmb_Class_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
shipClass = (cmb_Class.SelectedItem as ComboBoxItem).Content.ToString();
if (shipClass == "Scout")
{
attack = 6;
engine = 10;
shield = 8;
}
if (shipClass == "Warship")
{
attack = 10;
engine = 6;
shield = 8;
}
if (shipClass == "Cargo")
{
attack = 8;
engine = 6;
shield = 10;
}
if (shipClass == "Starliner")
{
attack = 6;
engine = 8;
shield = 10;
}
if (shipClass == "Transport")
{
attack = 8;
engine = 10;
shield = 6;
}
if (shipClass == "Luxury")
{
attack = 8;
engine = 8;
shield = 8;
}
lbl_Attack.Content = attack;
lbl_Engine.Content = engine;
lbl_Shield.Content = shield;
}
组合框cmb_Class中的项目全部硬编码到WPF格式xml中,标签就是我显示统计信息的方式。
奖金问题:我可以为类似的"物种"制作一个辅助文件。和他们的统计数据(是的,它是一个科幻RPG类型的东西),但如果有一个简单的方法将它们全部放在同一个文件中,那就太棒了。
答案 0 :(得分:1)
这是您可能想要使用的内容。它不使用XML,它使用CSV,但您可以轻松扩展它。
首先,您需要一个班级代表您的船只,如下所示。
public class Ship
{
public string Class { get; set; }
public int Attack { get; set; }
public int Engine { get; set; }
public int Shield { get; set; }
}
在此之后,你需要一种从某种数据源读取你的船只的方法:文件,数据库等。这个来源可以改变,所以你最好在下面的界面后面抽象它。
interface IShipRepository
{
List<Ship> GetShips();
}
在决定从哪里获得船只之后,您可以在IShipRepository接口的实现中编写它。下面的代码显示了如何从CSV文件中读取它。
public class CSVShipRepository : IShipRepository
{
private readonly string filePath;
public CSVShipRepository(string filePath)
{
if (string.IsNullOrEmpty(filePath))
throw new ArgumentNullException("filePath");
this.filePath = filePath;
}
public List<Ship> GetShips()
{
var res = new List<Ship>();
try
{
string fileData;
using (var sr = new StreamReader(filePath))
{
fileData = sr.ReadToEnd();
}
//class, attack, engine, shield
string[] lines = fileData.Split(new string[] { "\n" }, StringSplitOptions.RemoveEmptyEntries);
bool first = true;
foreach (var line in lines)
{
if (first)
{//jump over the first line (the CSV header line)
first = false; continue;
}
string[] values = line.Split(new string[] { "," }, StringSplitOptions.None)
.Select(p=>p.Trim()).ToArray();
if (values.Length != 4) continue;
var ship = new Ship() {
Class=values[0],
Attack=int.Parse(values[1]),
Engine = int.Parse(values[2]),
Shield = int.Parse(values[3]),
};
res.Add(ship);
}
}
catch (Exception ex)
{
Debug.WriteLine("error reading file: " + ex.Message);
}
return res;
}
}
现在你要做的就是在你的代码中使用这个CSVShipRepository。我们将使用一些小数据绑定,如下所示。
public partial class MainWindow : Window, INotifyPropertyChanged
{
private IShipRepository repository = new CSVShipRepository("d:\\test_data.csv");
private List<Ship> ships;
private Ship selectedShip;
public MainWindow()
{
InitializeComponent();
DataContext = this;
}
public List<Ship> Ships
{
get
{
if (ships == null)
ships = repository.GetShips();
return ships;
}
}
public Ship SelectedShip
{
get { return selectedShip; }
set
{
if (selectedShip == value) return;
selectedShip = value;
NotifyChanged("SelectedShip");
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void NotifyChanged(string name)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
}
相应的XAML在下面。
<ComboBox ItemsSource="{Binding Ships}"
SelectedItem="{Binding SelectedShip, Mode=TwoWay}" Margin="2">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Class}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<TextBlock Grid.Row="1" Text="{Binding SelectedShip.Attack}" Margin="3" />
<TextBlock Grid.Row="2" Text="{Binding SelectedShip.Engine}" Margin="3" />
<TextBlock Grid.Row="3" Text="{Binding SelectedShip.Shield}" Margin="3" />
希望这就是你所需要的。它比XML更简单,因为你的朋友不知道代码。这是一些样本数据
class, attack, engine, shield
demo, 1, 2, 3
demo2, 4, 5, 6