我有一个MainPage和MainPageViewModel,在viewmodel上,我具有以下属性,将一个listview绑定到:
public ObservableCollection<TargetDrawingModel> TargetDrawings { get; set; }
在视图模型上,我有以下方法(通过与按钮绑定到的相应命令运行):
private void AddTargetDrawingClick()
{
DataAccess da = new DataAccess();
TargetDrawings.Add(da.AddtoTargetDrawingList());
}
最后,DataAccess类中的AddToTargetDrawingList()方法:
public TargetDrawingModel AddtoTargetDrawingList()
{
TargetDrawingModel output = new TargetDrawingModel();
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Title = "Select The Target Drawings To Add To Add To The Comparison";
openFileDialog.Filter = "Drawing (*.dwg) | *.dwg";
openFileDialog.Multiselect = true;
if (openFileDialog.ShowDialog() == true)
{
foreach (string file in openFileDialog.FileNames)
{
TargetDrawingModel targetDrawing = new TargetDrawingModel();
targetDrawing.DrawingPath = file;
return targetDrawing;
}
}
output.DrawingPath = "nothing added";
return output;
}
该方法可以添加文件,但是如果我的用户未选择图形(取消打开文件对话框),我不想返回任何内容,但是,如果我不这样做提供一个返回值,该方法将不会生成,因为“并非所有代码路径都返回一个值”。这就是为什么我当前返回字符串“ nothing add”,但是显然不会这样做。
我怀疑是因为我正在ObservableCollection<TargetDrawingModel>
上调用Add方法。它要求我退货,但是我不确定该如何做。
如何修改此方法,以允许用户取消选择任何内容?
答案 0 :(得分:2)
在AddtoTargetDrawingList
方法中,您正在循环内执行一个返回语句,但是该方法将在遇到的第一个返回语句时退出,并且始终仅返回一个项目。如果要返回几个文件,可以使用yield return。这将方法变成迭代器。返回类型必须为IEnumerable<T>
。
public IEnumerable<TargetDrawingModel> GetTargetDrawingModels()
{
using (var openFileDialog = new OpenFileDialog() {
Title = "Select The Target Drawings To Add To Add To The Comparison",
Filter = "Drawing (*.dwg) | *.dwg",
Multiselect = true
}) {
if (openFileDialog.ShowDialog()) {
foreach (string file in openFileDialog.FileNames) {
yield return new TargetDrawingModel { DrawingPath = file };
}
}
}
}
现在您可以使用以下方式创建收藏集
TargetDrawings = new ObservableCollection<TargetDrawingModel>(da.GetTargetDrawingModels());
或者您可以使用foreach来添加它们
foreach (var model in da.GetTargetDrawingModels()) {
TargetDrawings.Add(model);
}
您还可以将System.Linq
命名空间中的扩展方法应用于类似ToList()
的结果
List<TargetDrawingModel> list = da.GetTargetDrawingModels().ToList();
yield return
不会终止该方法。而是返回一个结果并暂停。当检索到下一个元素时(例如通过foreach循环),该方法恢复。最后不必是yield return
或return
。如果取消了file-open-dialog,则会自动返回一个空的枚举。
另一种选择是使用正常的返回语句,但使用LINQ query来打包结果。此变体要求所有路径都具有返回语句。我们在方法末尾显式返回一个空枚举。
public IEnumerable<TargetDrawingModel> GetTargetDrawingModels2()
{
using (var openFileDialog = new OpenFileDialog() {
Title = "Select The Target Drawings To Add To Add To The Comparison",
Filter = "Drawing (*.dwg) | *.dwg",
Multiselect = true
}) {
if (openFileDialog.ShowDialog()) {
return openFileDialog.FileNames
.Select(f => new TargetDrawingModel { DrawingPath = f });
}
}
return Enumerable.Empty<TargetDrawingModel>();
}
答案 1 :(得分:1)
在添加到集合之前验证结果
var result = da.AddtoTargetDrawingList();
if (result != null && result.DrawingPath != "nothing added")
TargetDrawings.Add(result);
AddtoTargetDrawingList
使用多选FileDialog,这意味着您必须返回多个项目:
public IList<TargetDrawingModel> AddtoTargetDrawingList()
{
var items = new List<TargetDrawingModel>();
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Title = "Select The Target Drawings To Add To Add To The Comparison";
openFileDialog.Filter = "Drawing (*.dwg) | *.dwg";
openFileDialog.Multiselect = true;
if (openFileDialog.ShowDialog() == true)
{
foreach (string file in openFileDialog.FileNames)
{
TargetDrawingModel targetDrawing = new TargetDrawingModel();
targetDrawing.DrawingPath = file;
items.Add(targetDrawing);
}
}
return items;
}
foreach(var result in da.AddtoTargetDrawingList())
{
TargetDrawings.Add(result);
}