C
C#2y ago
Kosta

❔ Why do my source generated properties are unreacheable in code? using mvvm toolkit

Hello i got the following code:
public partial class CalculatorVM : ObservableObject
{
[ObservableProperty]
private int buttonOne = 1;

[ObservableProperty]
private int buttonTwo = 2;

[ObservableProperty]
private int buttonThree = 3;

[ObservableProperty]
private int buttonFour = 4;

[ObservableProperty]
private int buttonFive = 5;

[ObservableProperty]
private int buttonSix = 6;

[ObservableProperty]
private int buttonSeven = 7;

[ObservableProperty]
private int buttonEight = 8;

[ObservableProperty]
private int buttonNine = 9;

[ObservableProperty]
private double result, lastNumber;

[ObservableProperty]
SelectedOperator selectedOperator;

[ObservableProperty]
private int clickedNumber;

[ObservableProperty]
private Label resultLabel;



[RelayCommand]
public void NumbercClicked(int number)
{
var selectedNumber = number switch
{
1 => ButtonOne,
2 => ButtonTwo,
3 => ButtonThree,
4 => ButtonFour,
5 => ButtonFive,
6 => ButtonSix,
7 => ButtonSeven,
8 => ButtonEight,
9 => ButtonNine,

};
ClickedNumber = selectedNumber;
if (ClickedNumber == 0) Result = 0;
else Result = Result + selectedNumber;


}
public partial class CalculatorVM : ObservableObject
{
[ObservableProperty]
private int buttonOne = 1;

[ObservableProperty]
private int buttonTwo = 2;

[ObservableProperty]
private int buttonThree = 3;

[ObservableProperty]
private int buttonFour = 4;

[ObservableProperty]
private int buttonFive = 5;

[ObservableProperty]
private int buttonSix = 6;

[ObservableProperty]
private int buttonSeven = 7;

[ObservableProperty]
private int buttonEight = 8;

[ObservableProperty]
private int buttonNine = 9;

[ObservableProperty]
private double result, lastNumber;

[ObservableProperty]
SelectedOperator selectedOperator;

[ObservableProperty]
private int clickedNumber;

[ObservableProperty]
private Label resultLabel;



[RelayCommand]
public void NumbercClicked(int number)
{
var selectedNumber = number switch
{
1 => ButtonOne,
2 => ButtonTwo,
3 => ButtonThree,
4 => ButtonFour,
5 => ButtonFive,
6 => ButtonSix,
7 => ButtonSeven,
8 => ButtonEight,
9 => ButtonNine,

};
ClickedNumber = selectedNumber;
if (ClickedNumber == 0) Result = 0;
else Result = Result + selectedNumber;


}
I cant compile, tells me buttonOne etc dont exsist in the current context, The Repo: https://github.com/KostaKing/Calculator/tree/master/Calculator/ViewModels Anybody has any idea?
GitHub
Calculator/Calculator/ViewModels at master · KostaKing/Calculator
Contribute to KostaKing/Calculator development by creating an account on GitHub.
139 Replies
Kosta
KostaOP2y ago
No ideas? 😄
Anton
Anton2y ago
where does it say that and lol that code looks cringe idk what's the proper way of doing this but it's kinda cringe nonetheless and what are those properties for buttons for why are you using .net framework?
Google
Google2y ago
I thought if you wanted to use attributes on the properties you had to use an attribute on the class.
Anton
Anton2y ago
they have inherited ObservableObject
Google
Google2y ago
I know. I thought they had to use the attribute instead.
Anton
Anton2y ago
you can do either one in that library the attribute just mixes in the code that's in that base class
Google
Google2y ago
inheritance has fewer options and doesn't require partial public class MainWindowViewModel : ObservableObject is what I have right now.
Anton
Anton2y ago
having code gen for the props requires partial anyway and inheriting generates less code
Google
Google2y ago
and they want to generate the Command stuff I bet you their code right now says unnecessary partial or whatever.
Anton
Anton2y ago
anyway, you can switch to the attribute any time
Google
Google2y ago
Which is what they can do to fix the issue. Which was my first comment.
Anton
Anton2y ago
unnecessary partial is not an error tho + the issue they mentioned says something else
Google
Google2y ago
Google
Google2y ago
Which is weird, because I just tested it out, and it was just what I said
Anton
Anton2y ago
well just add the partial sure
Google
Google2y ago
actually, we still don't know what their error message is
Anton
Anton2y ago
the attribute vs base class is not part of the issue
antimatter8189
Hey its me , using a dif pc anyways. code is cringe atm trying to converts a shit code into a normal once, just work in process Cuz i have to old codebase
Anton
Anton2y ago
You can keep using .net framework, but with sdk-style projects
antimatter8189
Did you guys come to a solution? on to why i cant use those properties?
Anton
Anton2y ago
where's the error
antimatter8189
Well it tells me those properties that i defined are not accessible in the current context all of them
Anton
Anton2y ago
ah I think I caught on to it
antimatter8189
the codegen does happen
Anton
Anton2y ago
well the properties have different names than the fields
antimatter8189
you can grab the project its open on github, when u run it and click 1 you'll see
Anton
Anton2y ago
look at the generated code
antimatter8189
Yup they do it makes them capitilized
Anton
Anton2y ago
they are in pascal case
antimatter8189
im using the Cap ones as i should
Anton
Anton2y ago
I cant compile, tells me buttonOne etc dont exsist in the current context,
antimatter8189
acessing the field not the propery yeah but i pasted the code lol you can see im using the propery thats generated not the field if you download the project and rebuild it you'll see the errors in the output but when u f12 the "ButtonOne" it does go into the generated code
Anton
Anton2y ago
Why are they observable anyway? do you ever change their values? just make getters public int ButtonOne => 1
antimatter8189
Nop, but it doesnt matter Result needs to be and it cant locate it either problem is not only buttons, all the props are invisible
Anton
Anton2y ago
Anton
Anton2y ago
I wonder why see the problem?
antimatter8189
initilazing the datacontex in the back? hmm explain
Anton
Anton2y ago
swap these lines around
thebeardedquack
InitializeComponent() will cause UI updates. UI items pull information from the DataContext DataContext does not exist during InitializeComponent()
Anton
Anton2y ago
it uses the view as the datacontext this
thebeardedquack
Ew
Anton
Anton2y ago
I think
antimatter8189
Hmm, what?
thebeardedquack
As far as I'm concerned the View should have no code whatsoever. The ViewModel should have no idea about UI, whatsoever. Everything, is done via binding. The data context for your View, is the ViewModel, and the two are connected via binding
Anton
Anton2y ago
It uses the current instance of MainWindow as the data context so it's trying to find those properties on this
antimatter8189
I did nothing happened
Anton
Anton2y ago
unless you reset the data context to the view model first
thebeardedquack
This is MVVM, so you should have a MainWindowView and a MainWindowViewModel
antimatter8189
Kinda weak on that still learning can you elaborate on that?
thebeardedquack
The MainWindowViewModel is the DataContext for a MainWindowView. Your MVVM framework should be able to automatically select the View, when you tell it to display a ViewModel
Anton
Anton2y ago
well do you know how bindings work even?
antimatter8189
depends on what lvl , but yeah basically
Anton
Anton2y ago
INotifyPropertyChanged? Reflection?
antimatter8189
Yes i know those
Anton
Anton2y ago
Well, InitializeComponent creates your UI tree it creates the bindings it sets the bindings the data context is the object against which the bindings are created
thebeardedquack
I just looked at your project repo... Where's your views?
antimatter8189
there is 1 view, mainview but if i do this
DataContext = new CalculatorVM();

InitializeComponent();
DataContext = new CalculatorVM();

InitializeComponent();
Then the datacontex should be set to vm then initialized
Anton
Anton2y ago
when a binding for ButtonOne is created, it uses reflection to access the property ButtonOne on the data context, and subs to PropertyChanged of ButtonOne
thebeardedquack
How does your MVVM framework know that it should connect "MainWindow" which is not named "View" with "CalculatorVM" which is also not named with "ViewModel"?
Anton
Anton2y ago
well vm is your data context it is supposed to be at least
antimatter8189
IDK? learning stage atm but if i manually inject it should know no matter what they called no?
thebeardedquack
If you're learning, keep it super simple for yourself. Have a MainWindowView.xaml and a MainWindowViewModel.cs
antimatter8189
like how do i fix this guys, whats the solution whats the root cause
thebeardedquack
MVVM usually has some reflection under the hood that gets the class name and replaces "ViewModel" with "View"
antimatter8189
Lets say i want to keep it as it is @TheBeardedQuack and i just want to make it work like it is why dont it?
Anton
Anton2y ago
yeah it's fine
antimatter8189
where does the binding fail? I know this isnt proper code just focusing on other issue atm why cant it acess the ButtonOne property
Anton
Anton2y ago
it should work if you set the data context to the view model
thebeardedquack
I'm not familiar with your particular MVVM toolkit... Most of what I've seen uses properties, not fields, and doesn't require attribute decorations
Anton
Anton2y ago
are you sure the code is getting generated? I mean, source generators is a new feature
antimatter8189
Yes it is @AntonC , you can click it and see
Anton
Anton2y ago
I'm not sure they even work with non sdk style projects
antimatter8189
f12 it and you;ll go into generated code
Anton
Anton2y ago
I'm not looking at your code rn I don't wanna clone
antimatter8189
sample:
{
/// <inheritdoc cref="buttonOne"/>
[global::System.CodeDom.Compiler.GeneratedCode("CommunityToolkit.Mvvm.SourceGenerators.ObservablePropertyGenerator", "8.1.0.0")]
[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
public int ButtonOne
{
get => buttonOne;
set
{
if (!global::System.Collections.Generic.EqualityComparer<int>.Default.Equals(buttonOne, value))
{
OnButtonOneChanging(value);
OnPropertyChanging(global::CommunityToolkit.Mvvm.ComponentModel.__Internals.__KnownINotifyPropertyChangingArgs.ButtonOne);
buttonOne = value;
OnButtonOneChanged(value);
OnPropertyChanged(global::CommunityToolkit.Mvvm.ComponentModel.__Internals.__KnownINotifyPropertyChangedArgs.ButtonOne);
}
}
}

/// <inheritdoc cref="buttonTwo"/>
[global::System.CodeDom.Compiler.GeneratedCode("CommunityToolkit.Mvvm.SourceGenerators.ObservablePropertyGenerator", "8.1.0.0")]
[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
public int ButtonTwo
{
get => buttonTwo;
set
{
if (!global::System.Collections.Generic.EqualityComparer<int>.Default.Equals(buttonTwo, value))
{
OnButtonTwoChanging(value);
OnPropertyChanging(global::CommunityToolkit.Mvvm.ComponentModel.__Internals.__KnownINotifyPropertyChangingArgs.ButtonTwo);
buttonTwo = value;
OnButtonTwoChanged(value);
OnPropertyChanged(global::CommunityToolkit.Mvvm.ComponentModel.__Internals.__KnownINotifyPropertyChangedArgs.ButtonTwo);
}
}
}
{
/// <inheritdoc cref="buttonOne"/>
[global::System.CodeDom.Compiler.GeneratedCode("CommunityToolkit.Mvvm.SourceGenerators.ObservablePropertyGenerator", "8.1.0.0")]
[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
public int ButtonOne
{
get => buttonOne;
set
{
if (!global::System.Collections.Generic.EqualityComparer<int>.Default.Equals(buttonOne, value))
{
OnButtonOneChanging(value);
OnPropertyChanging(global::CommunityToolkit.Mvvm.ComponentModel.__Internals.__KnownINotifyPropertyChangingArgs.ButtonOne);
buttonOne = value;
OnButtonOneChanged(value);
OnPropertyChanged(global::CommunityToolkit.Mvvm.ComponentModel.__Internals.__KnownINotifyPropertyChangedArgs.ButtonOne);
}
}
}

/// <inheritdoc cref="buttonTwo"/>
[global::System.CodeDom.Compiler.GeneratedCode("CommunityToolkit.Mvvm.SourceGenerators.ObservablePropertyGenerator", "8.1.0.0")]
[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
public int ButtonTwo
{
get => buttonTwo;
set
{
if (!global::System.Collections.Generic.EqualityComparer<int>.Default.Equals(buttonTwo, value))
{
OnButtonTwoChanging(value);
OnPropertyChanging(global::CommunityToolkit.Mvvm.ComponentModel.__Internals.__KnownINotifyPropertyChangingArgs.ButtonTwo);
buttonTwo = value;
OnButtonTwoChanged(value);
OnPropertyChanged(global::CommunityToolkit.Mvvm.ComponentModel.__Internals.__KnownINotifyPropertyChangedArgs.ButtonTwo);
}
}
}
its generated alright.
thebeardedquack
ButtonOne is not a property that exists from what I can see on CalculatorVM.cs buttonOne exists
antimatter8189
yeah but thats the field i want to acess the prop
thebeardedquack
What property?
Anton
Anton2y ago
they're using MVVM community toolkit
antimatter8189
this one:
/// <inheritdoc cref="buttonOne"/>
[global::System.CodeDom.Compiler.GeneratedCode("CommunityToolkit.Mvvm.SourceGenerators.ObservablePropertyGenerator", "8.1.0.0")]
[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
public int ButtonOne
{
get => buttonOne;
set
{
if (!global::System.Collections.Generic.EqualityComparer<int>.Default.Equals(buttonOne, value))
{
OnButtonOneChanging(value);
OnPropertyChanging(global::CommunityToolkit.Mvvm.ComponentModel.__Internals.__KnownINotifyPropertyChangingArgs.ButtonOne);
buttonOne = value;
OnButtonOneChanged(value);
OnPropertyChanged(global::CommunityToolkit.Mvvm.ComponentModel.__Internals.__KnownINotifyPropertyChangedArgs.ButtonOne);
}
}
}
/// <inheritdoc cref="buttonOne"/>
[global::System.CodeDom.Compiler.GeneratedCode("CommunityToolkit.Mvvm.SourceGenerators.ObservablePropertyGenerator", "8.1.0.0")]
[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
public int ButtonOne
{
get => buttonOne;
set
{
if (!global::System.Collections.Generic.EqualityComparer<int>.Default.Equals(buttonOne, value))
{
OnButtonOneChanging(value);
OnPropertyChanging(global::CommunityToolkit.Mvvm.ComponentModel.__Internals.__KnownINotifyPropertyChangingArgs.ButtonOne);
buttonOne = value;
OnButtonOneChanged(value);
OnPropertyChanged(global::CommunityToolkit.Mvvm.ComponentModel.__Internals.__KnownINotifyPropertyChangedArgs.ButtonOne);
}
}
}
auto generated
thebeardedquack
I assume that's something handled by your toolkit
Anton
Anton2y ago
it autogenerates the properties
antimatter8189
yup
thebeardedquack
That looks nasty XD
Anton
Anton2y ago
it just saves you a bunch of boilerplate
Anton
Anton2y ago
well paste the error it gives you when you click or whatever
antimatter8189
i cant launch the program
Anton
Anton2y ago
compilation error then
antimatter8189
CS0103: The name 'ButtonOne' does not exist in the current context on all of the properties all of them
Anton
Anton2y ago
in what context
antimatter8189
just says current contex
Anton
Anton2y ago
what line the error is at
antimatter8189
CalculatorVM.cs(63,22,63,31)
Anton
Anton2y ago
I mean, paste the relevant bit here
antimatter8189
1 => ButtonOne, [ObservableProperty] private int buttonOne = 1;
Anton
Anton2y ago
nah it feels like the code doesn't get generated, or your ide doesn't recognize it restart the ide or like the other way your ide generates the code on the side
antimatter8189
did multiple times also the pc itself
Anton
Anton2y ago
but the compiler doesn't recognize it
antimatter8189
yup most likely i dont get why
Anton
Anton2y ago
I mean, source gen is a new feature
antimatter8189
yeah but it does source gen which is odd there was a fix for it cuz 4.8 didnt nativley support it
Anton
Anton2y ago
migrate to sdk style projects you should do it anyway
antimatter8189
I cant, not my choice millions of lines project, im a simple bolt
Anton
Anton2y ago
why not? you don't lose anything
antimatter8189
Cuz its not up 2 me
Anton
Anton2y ago
you don't have to use .net core you can keep using framework it's just that the project file will become simpler
antimatter8189
would you tell google rewrite X sofware for my Standars ? no you wouldnt Same thing here
Anton
Anton2y ago
I'm not telling you to rewrite the code just the project file there should be tools that can do this automatically even
antimatter8189
who says that would help anyways? feels like shooting in the dark we have no idea why the source gen isnt working proeprly we have no idea if doing the sdk thing will actually solve anything aye we need some c# / mvvm gods in this thread
Anton
Anton2y ago
I asked it in #roslyn wait for people to drop by Anyways, what's up with that code anyway why are those observable and why are you mapping them in that switch
Anton
Anton2y ago
Anton
Anton2y ago
Is this a ui element I'm seeing here?
antimatter8189
btw
antimatter8189
Stack Overflow
Community Toolkit MVVM doesn't bind data between View and View Mode...
My ViewModel partial class TestViewModel : ObservableObject { [ObservableProperty] private string inputText; } My View <Window x:Class="WpfApp_framework.MainWindow&...
antimatter8189
yeah its irrelevant thats how i made source gen work
Anton
Anton2y ago
well congrats, you've partially migrated to sdk style
antimatter8189
lol I've never developed an SDK dont even know where to begin on that and that benifits it grants me, but it doesnt have anything to do with the issue at hand probably
Anton
Anton2y ago
They just look like this https://github.com/AntonC9018/uni_csharp/blob/master/sem2_lab1/lab1.csproj I think you should just change the command parameter to a constant and remove those properties altogether
antimatter8189
I can change alot of things and make it work i want to know why it doesnt work as is
Anton
Anton2y ago
well now it does right?
antimatter8189
?
Anton
Anton2y ago
did that error go away?
antimatter8189
I did nothing? why would it go away? you want me to copy that github code?
Anton
Anton2y ago
well you said you solved the problem by adding that package reference
antimatter8189
Where did i say that? 😄 problem hasnt been solved at all
Anton
Anton2y ago
.
antimatter8189
same problem presists Code gen yes but not the "out of context" part
Anton
Anton2y ago
right
antimatter8189
Like i said, im getting the codegen even pasted here above i just cant access the generated properties for some odd reason
Anton
Anton2y ago
Well I think it's because you have to add the generated files to the compilation manually
antimatter8189
Cuz its a 4.8? common gotta be a workaround lol if the gen happens
Anton
Anton2y ago
because you're not using sdk style it would include them manually the workaround, or rather the solution, is to migrate to sdk style
antimatter8189
But it does work on .net 6? makes no sense
Anton
Anton2y ago
like I already told you 5 times
antimatter8189
u dont need sdk for .net 6 to make it work i want to make it work on 4.8 simple as that
Anton
Anton2y ago
idk wait for the experts to wake up in the roslyn channel
antimatter8189
Yup lol still here, still stuck 😄
Accord
Accord2y ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.

Did you find this page helpful?