前言
一到食堂发现有多种选择,但是有一个固定的套路,只能是一个荤,二个小荤,菜品数量也不少,任君选择,如果是一个选择困难症,就有点烦了,所以出品这个自动生成套餐软件。各位老板可以选菜了,还可以拆除一些不想要的菜,不勾选的菜就不会被选择。
一、效果展示
二、代码实现
1、WPF前台代码
<StackPanel x:Name="OptionalMenu" Orientation="Horizontal" Grid.RowSpan="2">
<GroupBox Header="组别1" x:Name="group1" Margin="0,5,50,0" FontSize="20">
<ScrollViewer VerticalScrollBarVisibility="Auto" >
<StackPanel x:Name="groupPanel1" />
</ScrollViewer>
</GroupBox>
<GroupBox Header="组别2" x:Name="group2" Margin="0,5,50,0" FontSize="20">
<ScrollViewer x:Name="scrList" Margin="0" VerticalScrollBarVisibility="Auto" >
<StackPanel x:Name="groupPanel2">
</StackPanel>
</ScrollViewer>
</GroupBox>
</StackPanel>
<Button Grid.Column="1" Height="30" Width="100" Click="Button_Click" Background="Cyan" FontSize="20"
Foreground="ForestGreen">选择</Button>
<RichTextBox Grid.Column="1" Grid.Row="1" Background="BlanchedAlmond" Name="logInfo" FontSize="18">
</RichTextBox>
2、后台业务
1)、初始化数据
主要是从XML加载菜单,这个XML后期可以根据实际情况进行调整。
public void InitToolInfo(string filename)
{
XmlDocument doc = new XmlDocument();
doc.Load(filename);
XmlNode xn = doc.SelectSingleNode("Mean");//要读取xml子目录路径
XmlNodeList xnl = xn.ChildNodes;
foreach (var item in xnl)
{
string sts = "";
XmlElement xe = (XmlElement)item;
sts = xe.GetAttribute("id");
XmlNodeList xnl0 = xe.ChildNodes;
List<MeanItem> newList = new List<MeanItem>();
for (int i = 0; i < xnl0.Count; i++)
{
string info = xnl0.Item(i).InnerText;
MeanItem data = new MeanItem(info,sts);
newList.Add(data);
}
mainMeanColls[sts] = newList;
}
}
2)、绑定控件与数据源
private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
keys = mainMeanColls.Keys.ToArray();
if (keys.Length!=2)
{
MessageBox.Show("菜单加载异常!");
return;
}
group1.Header = keys[0];
foreach (var item in mainMeanColls[keys[0]])
{
CheckBox checkBox = new CheckBox();
checkBox.Style =(Style) this.FindResource("ckbStyle");
checkBox.Content = item.Name;
LinkContrToObj(checkBox, item);
groupPanel1.Children.Add(checkBox);
}
group2.Header = keys[1];
foreach (var item in mainMeanColls[keys[1]])
{
CheckBox checkBox = new CheckBox();
checkBox.Style = (Style)this.FindResource("ckbStyle");
checkBox.Content = item.Name;
LinkContrToObj(checkBox, item);
groupPanel2.Children.Add(checkBox);
}
}
3)、筛选框与源关联
private void LinkContrToObj(CheckBox box,MeanItem obj)
{
var myBinding = new Binding("IsHave")
{
Source = obj
};
// Bind the data source to the TextBox control's Text dependency property
box.SetBinding(CheckBox.IsCheckedProperty, myBinding);
}
4)、选菜逻辑
当然有心的同学可能会发现一个问题,这个选择一个菜品与上一个不重复的逻辑有点哪啥了 ,可以考虑先剔除上菜单中的一个菜品,再去选择这样就发型Whie循环了。
private void GetResult()
{
string res1 = ExecuChoose(mainMeanColls[keys[0]].Where(t => t.IsHave == true).ToList(),1);
string res2 = ExecuChoose(mainMeanColls[keys[1]].Where(t => t.IsHave == true).ToList(),2);
string res3 = ExecuChoose(mainMeanColls[keys[1]].Where(t => t.IsHave == true).ToList(),3);
while (res2==res3)
{
res3 = ExecuChoose(mainMeanColls[keys[1]].Where(t => t.IsHave == true).ToList(), 3);
}
string res4 = ExecuChoose(mainMeanColls[keys[1]].Where(t => t.IsHave == true).ToList(),4);
while (res4 == res2||res4==res3)
{
res4 = ExecuChoose(mainMeanColls[keys[1]].Where(t => t.IsHave == true).ToList(), 4);
}
OutInfo($"结果>>:{keys[0]}-{res1};{keys[1]}-{res2},{res3},{res4}");
}
private string ExecuChoose(List<MeanItem> items,int num)
{
Random random = new Random(int.Parse(DateTime.Now.ToString("HHmmssfff"))+num);
int a = random.Next(1, items.Count);
return items[a - 1].Name;
}
5)、数据结构
/// <summary>
/// 菜单节点项
/// </summary>
internal class MeanItem : INotifyPropertyChanged
{
public string Name { get; set; }
private bool isHave;
public bool IsHave
{
get => isHave;
set
{
if (value == isHave)
{
return;
}
isHave = value;
OnPropertyChanged("IsHave");
}
}
public string GroupName { get; set; }
public MeanItem()
{
IsHave = true;
}
public MeanItem(string name, string groupName) : this()
{
this.Name = name;
this.GroupName = groupName;
}
public MeanItem(string name, bool isHave, string groupName)
: this(name, groupName)
{
this.IsHave = isHave;
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
}
}
}
6)、XML菜单配置
<?xml version="1.0" encoding="utf-8" ?>
<Mean>
<group id="大荤">
<item >土豆牛肉</item>
<item >红烧鸭块</item>
<item >梅干菜肉</item>
<item >狮子头</item>
<item >蛋饺</item>
<item >凉拌猪头肉</item>
<item >口水鸡</item>
<item >炒猪肝</item>
<item >回锅肉</item>
<item >尖椒鸡丁</item>
<item >青椒猪肚</item>
<item >排骨</item>
<item >虾</item>
<item >香肠</item>
</group>
<group id="小荤">
<item >凉拌豆皮</item>
<item >凉拌海带</item>
<item >皮蛋豆腐</item>
<item >凉拌粉皮</item>
<item >凉拌黄瓜</item>
<item >雪菜蚕豆</item>
<item >红烧豆腐</item>
<item >毛豆肉丝</item>
<item >花菜</item>
<item >竹笋肉丝</item>
<item >豆芽粉丝</item>
<item >海鲜菇肉丝</item>
<item >西葫芦肉丝</item>
<item >土豆丝</item>
<item >青菜</item>
<item >尖椒炒蛋</item>
<item >芹菜肉丝</item>
<item >韭菜炒蛋</item>
<item >包菜</item>
<item >番茄炒蛋</item>
<item >凉拌木耳</item>
<item >青椒香干</item>
<item >青菜</item>
<item >尖椒炒蛋</item>
<item >芹菜肉丝</item>
<item >韭菜炒蛋</item>
<item >包菜</item>
<item >番茄炒蛋</item>
<item >凉拌木耳</item>
<item >青椒香干</item>
</group>
</Mean>