将列表<Model>转换为ObservableCollection<ViewModel>

问题描述 投票:0回答:2

我对 MVVM 实现相当陌生。这听起来像是一个重复的问题,但我找不到任何东西可以帮助我更好地理解我的基础知识。我有一个

Model
班级,其成员如下所示:

public class Model
{
    public string Name { get; set; }
    public int Age { get; set; }
    public List<Model> Children { get; set; }
}

我已将此模型类包装在视图模型中,但用

ObservableCollection
代替
List

public class ViewModel
{
    private Model model;
    public ViewModel()
    {
        model = new Model();
    }
    //getters and setters for both Name and Age

    public ObservableCollection<ViewModel> Children
    {
        //how to convert List<Model> to ObservableCollection<ViewModel> here?
    }
}

我绝对不想将我的

Model
类暴露给视图,这就是为什么我需要创建 VM 类的
ObservableCollection
。但不确定如何实现这一目标。任何帮助表示赞赏。

c# wpf mvvm
2个回答
6
投票

您可能正在寻找以下内容:

public class Model
{
    public string Name { get; set; }
    public int Age { get; set; }
    public List<Model> Children { get; set; }
}
public class ViewModel
{
    public ViewModel(Model m)
    {
        Name = m.Name;
        Age = m.Age;
        Children = new ObservableCollection<ViewModel>(m.Children.Select(md=>new ViewModel(md)));
    }

    public string Name { get; set; }
    public int Age { get; set; }
    public ObservableCollection<ViewModel> Children { get; set; }

    public Model GetModel()
    {
        return new Model()
        {
            Age = Age,
            Name = Name,
            Children = Children.Select(vm=>vm.GetModel()).ToList(),
        };
    }
}

您会注意到其中很多都是样板代码。但如果你这样做,你的模型/视图模型是完全分离的,这将为你节省很多问题。


0
投票

这是我的模型的 2 个类,并尝试为 ObservableCollection 找到解决方案

命名空间 GDAT.Models { 公共类 LogEntry { #region 属性 私有字符串? _信息; #结束区域

    #region Constructors
    public LogEntry(int id, string logLine)
    {
        this.RowNumber = id;

        try
        {
            var dateTimeStr = logLine.Substring(1, 19);

            DateTime = System.DateTime.ParseExact(dateTimeStr, "dd/MM/yyyy HH:mm:ss",
                System.Globalization.CultureInfo.InvariantCulture);

            logLine = logLine.Substring(21).Trim();

            var info = logLine
                .Split(':')
                .ToList();

            if (info.Any())
            {
                FileName = info.First().Trim();
                info.RemoveAt(0);
            }

            if (info.Any())
            {
                CodeLineNumber = int.Parse(info.First().Trim());
                info.RemoveAt(0);
            }

            if (info.Any())
            {
                FunctionName = info.First().Trim();
                info.RemoveAt(0);
            }

            Message = string.Join(':', info);

        }
        catch (Exception e)
        {
            Console.WriteLine($"Error creating LogEntry: {e.Message}");
        }
    }
    #endregion


    #region properties
    public int RowNumber { get; set; }

    public DateTime DateTime { get; set; }

    public string DateTimeFormat => this.DateTime.ToString("dd/MM/yyyy HH:mm:ss", System.Globalization.CultureInfo.InvariantCulture);

    public string FileName { get; set; }

    public int CodeLineNumber { get; set; }

    public string FunctionName { get; set; }

    public string? Message
    {
        get => _message;
        set
        {
            if (_message != value)
            {
                _message = value?.Replace("\t", " "); // Replace tabs with spaces

                while (_message?.Contains("  ") == true)  // Remove extra spaces
                {
                    _message = _message.Replace("  ", " ");
                }
            }
        }
    }
    #endregion
}

}

命名空间 GDAT.Models { 公共类日志数据 { #region 构造函数 公共日志数据() { LogList = new List(); }

    public void LoadData(string? filePath)
    {
        if (string.IsNullOrEmpty(filePath))
        {
            Console.WriteLine("File path is null or empty.");
            return;
        }

        if (!File.Exists(filePath))
        {
            Console.WriteLine("File does not exist.");
            return;
        } 
        
        FilePath = filePath;

        LogList.Clear();

        try
        {
            var lines = File.ReadAllText(FilePath)
                    .Replace("\r", String.Empty)
                    .Replace("\n", "\\n")
                    .Replace("\\n[", "\n[")
                    .Split('\n')
                    .Where(x => x.StartsWith("["))
                    .Select(x => x.Trim())
                    .ToArray();

            for (int index = 0; index < lines.Length; index++)
            {
                var line = lines[index];

                if (!line.Contains("****** FICHIER DE TRACE ******") && !line.Contains("****** FIN FICHIER DE TRACE ******"))
                {
                        LogList.Add(new LogEntry(index + 1, line));
                }
            }
        }
        
        catch (Exception ex)
        {
                Console.WriteLine("Error while loading data: " + ex.Message);
        }
    }
    #endregion


    #region Properties
    public string? FilePath { get; private set; }

    public List<LogEntry> LogList { get; set; }
    #endregion
}

}

我是初学者,将列表转换为 ObservableCollection 非常复杂

你能帮我吗,因为我正在研究 MVVM 模型,我尝试将模型和视图分开

谢谢

© www.soinside.com 2019 - 2024. All rights reserved.