使用 OpenFileDIalog 添加到 ObservableCollection<T>

Add to an ObservableCollection<T> using OpenFileDIalog

我有一个 MainPage 和 MainPageViewModel,在视图模型上我有以下 属性 我正在将一个列表视图绑定到:

public ObservableCollection<TargetDrawingModel> TargetDrawings { get; set; }

在视图模型上,我有以下方法(运行 通过我的按钮绑定到的相应命令):

private void AddTargetDrawingClick()
{
    DataAccess da = new DataAccess();
    TargetDrawings.Add(da.AddtoTargetDrawingList());
}

最后,DataAccess 中的 AddToTargetDrawingList() 方法 class:

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;
}

该方法适用于添加文件,但如果我的用户没有 select 绘图(取消打开文件对话框),我 不想 return 任何东西,但是,如果我不提供 return 值,该方法将不会构建,因为 "Not all code paths return a value." 这就是为什么我目前正在 return 字符串 "nothing added" 但这显然不行。

我怀疑是因为我在 ObservableCollection<TargetDrawingModel> 上调用了 Add 方法。它需要我 return 一些东西,但我不确定如何做不同的事情。

如何修改此方法以允许用户取消 select 什么都不做?

添加到集合前验证结果:

var result = da.AddtoTargetDrawingList();
if (result != null && result.DrawingPath != "nothing added")
    TargetDrawings.Add(result);

AddtoTargetDrawingList 使用多选 FileDialog,这意味着您必须 return 多个项目:

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);
}

AddtoTargetDrawingList 方法中,您在循环内执行 return 语句,但该方法将在遇到第一个 return 语句时退出,并且始终只会 return 一项。如果你想 return 多个文件,你可以使用 yield return。这会将方法变成迭代器。 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 不会终止该方法。相反,它 return 是一个结果并暂停。当检索到下一个元素时(例如通过 foreach 循环),该方法将恢复。末尾不需要 yield returnreturn。如果取消文件打开对话框,则会自动 return 编辑空枚举。


另一种选择是使用普通的 return 语句,但使用 LINQ query 来打包结果。此变体要求所有路径都具有 return 语句。我们 return 在方法末尾显式地空枚举。

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>();
}