How to use the source generators from CommunityToolkit.Mvvm for a .NET Framework 4.7.2 WPF Application
Asked Answered
M

5

6

I recently tested the WPF UI library (https://wpfui.lepo.co/). I created a sample project, and that project targeted .NET 6.0. The sample project contained some basic Models and ViewModels, and in those files I found properties declared using the [ObservableProperty] attribute. I really liked how that reduced the amount of code needed for simple properties, so I wanted to use that for an existing project which targets .NET Framework 4.7.2.

But I don't know how or if it is even possible. Existing information that I find online is very confusing, but the accepted answer to this question sounds like it is possible: Roslyn Source Generator not generating any source in a .net framework 4.7.2

I tried the following, but the application won't build:

using CommunityToolkit.Mvvm.ComponentModel;

namespace MatlogUtility
{
    public partial class HeatListEntry : ObservableObject
    {
        [ObservableProperty]
        private int? heatListId;

    }
}
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Threading.Tasks;
using System.Windows;
using MatlogUtility.Models;


namespace MatlogUtility
{
    public static class SqlQueries
    {
        public static List<HeatListEntry> GetHeatList()
        {
            List<HeatListEntry> heatList = new List<HeatListEntry>();

            string queryString = "SELECT a as heatListId FROM someTable;";

            using (SqlConnection connection = new SqlConnection(Globals.ConnectionString))
            {
                SqlCommand command = new SqlCommand(queryString, connection);
                connection.Open();
                var reader = command.ExecuteReader();
                try
                {
                    while (reader.Read())
                    {
                        heatList.Add(new HeatListEntry
                        {
                            HeatListId = reader["heatListId"] == DBNull.Value ? null : (int?)reader["heatListId"]
                        });
                    }
                }
                finally
                {
                    // Always call Close when done reading.
                    reader.Close();
                }
            }

            return heatList;
        }
    }
}

The error list shows that 'HeatListEntry' does not contain a definition for HeatListId'

I also tried installing a bunch of NuGet-packages related to 'Roslyn', for example Microsoft.CodeAnalysis.CSharp and Microsoft.CSharp, but it still doesn't work.

Is what I am trying to do even possible? Thanks in advance, any pointers are appreciated!

Matz answered 27/9, 2022 at 9:15 Comment(1)
Currently only .NET Standard 2.0 assemblies can be used as Source Generators. So try to define your HeatListEntry class in a project that targets .NET Standard 2.0.Participial
A
5

I also got into the same issue. It seems MVVM Source Generators don't support older .net frameworks (till 4.8). I changed my project framework from 4.8 to .net 6 and it worked fine.
You can also try, Upgrade a WPF App to .NET 6 with the .NET Upgrade Assistant

Ayo answered 27/9, 2022 at 10:34 Comment(1)
i just did that, and it was less work than i expected :) I'll keep the question open for another day or so to see if somebody else has a different answer. if not, I'll accept yoursMatz
E
9

Worked with CommunityToolkit.Mvvm 8.0.0 for me in .NET 4.8:

  1. Right click the packages.config-File.
  2. Choose "Migrate packages.config to PackageReference..."

Also, you need to set the LangVersion to a minimum of 8.0

Ebner answered 9/1, 2023 at 13:28 Comment(3)
Thanks, this really helped! How did you know that the step Choose "Migrate packages.config to PackageReference..." fixes it? For others how to change LangVersion: open .csproj as text file and in <PropertyGroup> tag, place or replace the <LangVersion> tag, e.g. <LangVersion>9.0</LangVersion>Karlenekarlens
Not sure migrating to PackageReference will change something in this case...Statism
Migrating packages.config to PackageReference did it for me. No idea why this is not mentioned anywhere. Thanks!Poetics
A
5

I also got into the same issue. It seems MVVM Source Generators don't support older .net frameworks (till 4.8). I changed my project framework from 4.8 to .net 6 and it worked fine.
You can also try, Upgrade a WPF App to .NET 6 with the .NET Upgrade Assistant

Ayo answered 27/9, 2022 at 10:34 Comment(1)
i just did that, and it was less work than i expected :) I'll keep the question open for another day or so to see if somebody else has a different answer. if not, I'll accept yoursMatz
S
1

There is an issue with the .NET Framework: https://github.com/CommunityToolkit/dotnet/issues/158

The only workaround is to put your view models in a separate assembly targeting .NET Standard 2.0 with C# 10 or more.

Statism answered 22/11, 2023 at 8:4 Comment(0)
O
0

For me, in 4.7.2 projects, it is enough to perform 3 actions:

  1. add a link to the library CommunityToolkit.Mvvm.8.3.2\lib\netstandard2.0\CommunityToolkit.Mvvm.dll
  2. add a link to the library Сommunitytoolkit.mvvm\8.3.2\analyzers\dotnet\roslyn4.3\cs\CommunityToolkit.Mvvm.SourceGenerators.dll to the project analyzers
  3. Change the language to the latest latest

It works for me.

Project

Code

Run

It work

Overrun answered 2/10 at 10:52 Comment(1)
Please try to type the code instead of giving a screenshotRentfree
B
-1

Maybe a little later. But I'm using the "Microsoft.Toolkit.MVVM" (not CommunityToolkit.Mvvm) for .NET 4.6.2 in VB and it works fine. The MVVM framework does not autogenerate the property for the observable fields, but I manually created them. For example:

using Microsoft.Toolkit.Mvvm.ComponentModel;

public partial class MainViewModel : ObservableObject
{
    private string _name;
    [ObservableProperty]
    public string Name
    {
        get { return _name; }
        set { SetProperty(ref _name, value); }
    }

    private int _age;
    [ObservableProperty]
    public int Age
    {
        get { return _age; }
        set { SetProperty(ref _age, value); }
    }
}

I hope this can help in .net > 4.6.2

Bertram answered 4/8, 2023 at 17:52 Comment(2)
If you write the properties yourself, the ObservableProperty attribute is useless.Statism
Nope, work fine in .net 4.6.2.Bertram

© 2022 - 2024 — McMap. All rights reserved.