✅ Trying to figure out how to loop game Avalonia
GameEngineViewModel.cs
=> https://pastebin.com/36Sjrpnf
I have a button that I want to trigger showing the next question to the user. On the previous screen, they select how many questions they want to answer which is passed to the GameEngineViewModel through the Game game
=> game.TotalQuestions
parameter/variable. I'm trying to figure out how to loop the game for as many times as the game.TotalQuestions
number is and have the next question shown based off of a button click. This button is only visible after the user has submitted their answer and the WinLoseText shows to the user. How would I go about doing this? ThanksPastebin
public class GameEngineViewModel : ViewModelBase{ public string?...
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
642 Replies
I tried doing that, but how would I get the loop to know when the user clicked the
Next Question
button so that they can progress through the questions at their own pace
this is the function that runs the game. I tried wrapping the inner code in a for loop that would iterate for the number of game.TotalQuestions
but I couldn't get the button to work. I tried to do
so that NextQuestion was bound to the button and would return true when clicked so that the loop could continue after the button was clicked, but it wouldn't work right.
I have zero idea. This is the only thing holding up progression of this application😕 I have zero idea how to use that in my current code. Even looking at the docs, I'm lost
alright, what does your View consist of?
I'm actually going to hold off on this portion of the code. I realized that I've just been building by the fly of my pants and slapping things together instead of actually following a plan. I do apologize for getting back to you so late, however, I've spent the last 2 hours putting a build plan together of what each screen is supposed to do and how it's supposed to do it, and I'm going to start the project over. I appreciate your help and I'll be back when I come into another problem, or am ready to continue with this portion of the code.
ok I'm back to this part now
in the main window view model, this is what controls the game screen. How would I loop this for as many times as
SelectedTotalQuestions
or would I loop it inside of the view model?see prior question
https://pastebin.com/Wrj6g3S4 this is my view
alright
I see some labels
some more labels
a text box
another label
and three buttons
so, we're interested in the
Submit
command, yes?first I'm interested in getting the game to loop for the number of questions the user selected to answer. I have a button "Next Question" that is bound to
public ReactiveCommand<Unit, Unit> NextQuestion { get; }
in the view model. This button allows the next question to be shown upon user click so if the user elects to answer 5 questions, then the first question shows, the user answers, and then the Next Question button becomes visible to go to next question on user click
so this is the MainWindowViewModel control of the screen
https://pastebin.com/JfEdFW2g this is the view axaml file
https://pastebin.com/wtR5Gg1v this is the view model for that screen
so it's supposed to be like
okay, so, we're interested in the
NextQuestion
commandlike in a console based application, it woul dbe
right
this isn't a Console application
right. I was using that to relay what I was meaning in an easier way
so stop trying to jump around the problem and work the problem
you have a ViewModel to implement
the piece of it that you're having trouble with is
NextQuestion
focus on that
what is NextQuestion
supposed to do?go to the next question upon user click
do I put the loop in the main window view model or in the game engine view model?
is there a scenario where the user can't go to the next question?
no
k
go to the next questionhow do we do this? what assumptions does this imply?
that we have two functions and one always returns true?
I meant the text that I quoted
but I still don't know if this is going to be controlled by the main window view model or the game engine view model
stop asking questions that you don't even understand in the first place
we have a method to implement
focus on the problem
go to the next questionhow do we do this? what assumptions does this imply?
excuse me? I'm just simply asking where we're implementing the method. Jesus christ
it means to start the loop and pause it until the user clicks the next question button to continue the loop
what loop?
where is the loop in the context of the method we're implementing?
spoiler: there isn't one
if my goal is to "move to the next question", what does that imply?
how about "that there's a current question"
how about "that there is a set of questions"
no there isn't one yet because I don't know where to put it.
why do you assume there will be one?
so that there can be as many questions as the user wants to answer
why does that imply that you need a
for
loop?because that's the only thing I know to do. Unless you're talking about creating a backend class that gets passed the total number of questions that the user wants to answer, generating all the questions, and then displaying the screen with the first question in the list of questions and having the button refresh the screen and go to the next index in the list of questions
because that's the only thing I know to dowhich is why I'm trying to help you think through the problem, rather than try and work backwards from a solution that isn't actually applicable
so then I need to get the number of questions the user wants to answer, go ahead and generate all of them into a list, and then display
that would be the most straightforward thing to do
at the very least, you need SOME way to determine how many questions you want there to be
well it would be a list of lists since I display the numOne, operator, and numTwo in separate items on the screen
maybe you generate them all ahead of time, maybe you just keep a count of how many you want, and generate them on the fly
why does that imply a list of lists?
at the very least, you need SOME way to determine how many questions you want there to bethat's determined on the screen before this one. The home screen view model is where the user selects the difficulty and total questions to answer, and the game they want to play and that's pushed back to the main window view model, stored, and then passed to the game screen
great
that info gets passed to the GameEngineViewModel
it would be like
and I say that because I display NumOne in Label A, Operation in Label B, and NumTwo in Label C, but there could be a better way to do it. This is just what I thought of since I display the 3 items separately instead of in the same label
correct
...nooooooooooooo...
oooooooo, now you didn't tell me we're in RX-land
rx-land?
Reactive Extensions
yea it's reactive UI. I didn't know I needed to specify that? I thought that's what everyone used
if only
ok so here's what I've done so far and I want your thoughts
I've updated the game engine to this so far
and I've started a class in my services folder to build the list of questions
what do I do with this?
public List<Question> AllQuestions
is not something your View layer needs
that would be an RX-style way to implement your "loop"
build a stream of the questions
each time the stream emits a quesiton, push it to the View
throttle the stream to only emit one question each time the _nextQuestionExecuted event fires, I.E. when the button is clicked
when the stream completes, I.E. there are no more questions, fire an event to the owner VM that the game is doneok before I implement that, do you mind to help me get the BuildQuestions class finished? I'm not sure how to get the operation into the list
you don't have to implement that, especially if you don't understand it
just demonstrating possibilities
BuildQuestions
is a poor name for a class
maybe QuestionBuilder
or QuestionsService
tbh I like what I've done starting this class. If it's not the proper way to do it, then I can scratch it, but I like it lol
sure
regardless, your
BuildList()
method is what you want
what are diff
and gameType
?how would I get the Operation enum to know which item belongs to it's item in the list?
diff is the selected difficulty the user chose to play on and gameType is the game they chose to play
those should probably also be
enum
sthis game is for my niece who's in 3rd or 4th grade, so it's set to where if it's Multiplication or Division then it generates the NumOne and NumTwo in a different range than Addition and Subtraction
certainly
and, strictly-speaking, this belongs in your View layer
now, to be clear
I'm definitely going to illustrate an "idealized" way of doing all this stuff
but you are free to do what works
the dictionary belongs in the GameEngine?
if you want to just put these sybols straight into
Question.Operation
as string
s that's fine
this isn't an enterprise application
is GameEngine
a View
?
the View
for GameEngineViewModel
?that's called GameEngineView.axaml
either there, or within an
IValueConverter
depending on how you're doing bindingsoh so the dictionary goes in the GameEngineView.axaml.cs file
and you seem to be doing XAML bindings, so, an
IValueConverter
if that makes sense to you
and lets you use it in your bindingsI've never used the code behind file for anything, so if that's where it goes then I'll put it there
that isn't "where it goes"
put it where you need it to be
or where it makes sense to you
I'll leave it in the QuestionBuilder class then
well
I mean
like, do that
but my point is that what that dictionary is is a mapping of how to DISPLAY those enum values
it's specifically a VIEW layer concern
the proper place for it is somewhere in the View layer
then i'll put it in the game engines view model
which could be a lot of places, but not on the backend
QuestionBuilder
class, and not on a VMif it's neither of those then the only other place is the axaml.cs file
not necessarily
example
and doing that negates the dictionary altogether right?
in this case, yeah
sort of
you could still use a dictionary for miniscule performance boost
I put this into a ValueConverters.cs file and implemented the converter into the view where the operation is shown
ok I made those changes
and this is where I'm at on the question builder class.
sweet
ok so when trying to get the operation based off the gameType, it doesn't like
string
and I don't know what to put for parameter
okay, so
don't do that
oh. I was happy I got that far 😂
the point of making a
ValueConverter
was to keep the conversion logic in the View layer
this isn't the View Layer
if you're just going to do it here, use the dictionary
or a switch
or just forget the enumok I have to get the operation back to the game engine view model somehow
what would you suggest with having the value converter?
where I suggested earlier
what does that have to do with whether or not you do a conversion for display here?
done
or is it only one operation per game-type?
oh, I see now
one game type per operation, plus a random
right
absolutely do not call
.ToList()
so if on the home screen they click the Addition button, then it'll be all addition questions
sure
personally, I think you should split this stuff apart a bit
well, nevermind
next point
absolutely do not do this
do you mean build 5 different screens for the 5 game plays?
I was thinking more like 5 different methods on
QuestionBuilder()
one for each difficultyI can do that. I don't mind
whatever is more efficient
even if they're just
private
and BuildList()
just chooses which one to useand proper practice
but I changed my mind
I wouldn't say either way is "proper" for this one
both are valid
okie dokie. so with getting the operation in the GetOperation function, how do I need to call the list from the value converter and why shouldn't I do random like that?
proper usage of the
Random
class is to create one instance, and reuse it as much as possibleso put it at the top of the class => constructor
and just call it from there
or
this second one would allow you to create the
Random
instance in your Main method, or whatever
and share it across many different classes in the app that need to pull random numbers
each time you create a new instance of Random
, it creates a new sequence with a new seed
cryptographic pseudo-randomness is only guaranteed across numbers generated from the same sequencerandom is only used within this file. To generate the numbers to display and the random operation if the user selects to play a random game. As far as the rest of what you post, I'm beyond confused and don't know what half of that means so I have zero clue where to put this random thing.
one instance
reuse it
I don't have a question builder function. so I'm assuming I need to make one
you already have, I just didn't copy it here
then whoever is using
QuestionBuilder
, same thing. Create just one and reuse ityea I'm lost. I have zero idea.
then re-orient
what is the problem right now?
that is ALWAYS the first question to ask yourself
what is the problem you are trying to solve?
great
no that's not wher eI"m at
I'm fighting with this stupid keyboard
one moent please
well, it's how you got there
where you're ACTUALLY at is writing the
OperationBuilder.BuildList()
method
and you're there because that's what GameEngineViewModel
currently needsGameEngineViewModel => https://pastebin.com/kkBw832q
QuestionBuilder => https://pastebin.com/ikQZRXRS
ValueConverter => https://pastebin.com/23iftTjC
This is where I'm at with what has been built so far.
1. I have zero idea where or what I'm supposed to do with random. Completely lost there.
2. I have zero idea how to get the GetOperation function to work
3. I just feel beyond dumb
so, we're on
GetOperation()
what's the problem with GetOperation
?tbh I'm stuck on where and how to put random.
with get operation, I can't fgure out how to call the dang list from the value converter and whta to pass it
I can't figure out how to call the dang list from the value converteras I said, don't ValueConverter doesn't belong here
QuestionBuilder
is not part of the View layerhow do I get access to that rng variable because
QuestionBuilder
doesn't have it as a propertyuhh
yes it does
I mean
it's not a property, no
but... it's right there
where you put it
so, there's an error
what is it?
what does that mean to you?
had to make the priavte variable static
yes, but no
make the method not
static
ok. did that
I Have access to it just fine now
or make the entire class
static
but really, until you can explain in detail what static
means, don't use it
as a general recommendationthat's fine. So now onto the GetOperation function
with the one exception of your
Main()
method which HAS to be static
correct otherwise it doesn't have a property main entry point
😉
so, what's the issue with
GetOperation()
currently?why is
GetOperation()
returning string?
?because that's what it was previously set to. I haven't changed it yet, but I don't know what I'm returning out of the function yet since I can't figure out what to return
excellent answer
leads you right to the next question
where are you using
GetOperation()
so, the return value is being assigned to
Question.Operation
what is Question.Operation
?Operation?
that's what
GetOperation()
needs to returnI thought it was supposed to be a string
why?
because it's a string when displayed
is it an enum?
that's what
Operation
is, yes
and that's what my recommendation was for the Question
class
because the fact that it's going to be displayed as a string
is irrelevant in this layer
it's only relevant to the View layer
that was my point earlier
the View's job is to display thingsthe ViewModel/Business layer's job is to understand logic
right. In the question class, it's a required Operation
if the View wants to take that
Operation
enum value and display it as a string
then it's free to do so, and the ViewModel/Business layer doesn't need to know or carebut as a side question, why are the numbers set to decimals instead of integers when I have them as integers in teh view model?
because I didn't have the full picture of your ViewModel when I wrote that
makes sense
so I can change them to int's and be fine
if you only want to generate
int
s feel free to make those int
s, yesok cool
so what am I not understanding with the get operation function because I'm still lost there
while we're at it, I'm going to recommend the exact same thing for difficulty and gametype
so on this, the difficulty is just a simple string list in the home screen view model that the user selects from a combobox
Difficulties = new() { "Select One", "Easy", "Medium", "Hard" };
. As far as the game type, those are command parameters from the buttons on the home screen view
which is how the main window view model knows what screen to show
okay
?
ok
is that relevant to having difficulty and gameType be enums?
I thought it was which is why I explained what they're purpose was, but I'm guessing I was off on that.
sorry
no need to apologize, I'm not criticizing you
I'm trying to make you challenge your assumptions
in the same way that
Operation
being an enum is independent of how the View wants to display that value as a string
symbolso I'm making them enums for the logic, not for what I already have them for
how the View chooses to present commands to the user is irrelevant of how they're modeled in the business layer
you could say that
enums are standard practice for something like this for two main reasons
A) it's compiler-safe
if I am referencing the game type
Addition
in 7 different places, as a string
but in one place I accidentally type Adition
that's a bug that I won't find until that code runs
and even then, I might not figure it out right awayI got you
as an enum, if I type
Adition
the compiler immediately tells me that's an error, because Adition
is undefinedmakes sense
B) it clarifies your intent
if I see
I really have no idea what possible operations that could be
the only way I know is by having a greater contextual understanding of the whole application
with an enum, I can see EXACTLY what all possible values are supposed to be
and they're all defined in one central place
and that can actually help INFORM me about the greater context of the whole app
as far as mechanics, in the View layer....
I believe this should work
might be a bit off with the syntax
what's the difference with that and just using a string? That seems to overcomplicate what it's passing / usage for no reason
should be the equivalent of
as opposed to
which is the difference between your command in the ViewModel being....
versus
if this makes any difference, this is how those buttons are setup
point being if you're GOING to have an enum in the business layer
it should be the View's job to convert strings to that enum, if it needs to use strings in the View layer
but in this case, that's not even necessary
the View layer can use the enum directly, and there's no need for parsing/conversion logic
at this point I might as well either just scratch it and find her one that's already built, or literally just show you every single file of this project and redo the entire thing
A) I said earlier, I'm going to present an idealized way of structuring this, as a learning experience, but you are free to not implement it that way. So long as you understand the concepts.
B) Why is scrapping chunks of this and redoing them a bad thing? That's quite normal, even for experienced developers.
you're still learning, either way
it's nothing to do with, or against, you. I just can't get away from feeling like I'm always dumb with this stuff. Programming is my favorite thing to do. I can spend hours doing it and never get burnt out. Literally. I've been at it for 3+ years now. I've learned Python, Web Dev with ReactJS, and now I'm on C#, but in every language, I always feel like I'm more stupid than I'm actually doing anything right and it's no one fault but my own. It's a pride issue. I'll write out my code and be so proud of it and feel like I did the best work I can do, and then I'll share it and I've done it in such a newb way that I feel like I never learned anything and just threw plaster on the wall. What I've learned, I've learned from YouTube because my best friend who taught me Python has practically abandoned me because he'd rather spend all of his time doing debates and working with other people than with me anymore and so I lost that person that was there for me to program with all the time. I don't know how to read most documentation. With avalonia alone, the only documentation I know how to read is to pull up the control, click it's link and go to it's properties, and look at its styling file on the repo. I'm great with front end stuff. Always have been since I started with react js, but with this logic crap and backend stuff, it's just so difficult for me to grasp the concept of and I always feel stupid regardless to what I learn.
TL:DR => the problem is me
I'm sorry to hear that
but this is also, still, rather normal
there will always be things you don't know
and techniques you've never thought of
so given that I've changed the command parameters to this, how does my view model need to change?
that's why programming IS a collaborative profession
I know and you're right. I just can't get past my own self with it
assuming I'm right about that syntax, each of your commands now takes
GameType
instead of string
as its input parameter
bblhttps://pastebin.com/KeYRcgtF this is the view model for those buttons
ok so with making changes
I now have changed my
game model, and I have changed all the strings that were associated with the game type to GameTypes in the HomeScreenViewModel
now to make the changes with the Difficulties
so since my game model no longer takes Difficulty as a string, how do I need to do my list
Difficulties = new() { "Select One", "Easy", "Medium", "Hard" };
?
so I've changed these
I dont 'know how to fix these
or these
I changed these to match as wellhttps://pastebin.com/MQYj5tfr I think I got it figured out
Pastebin
using ReactiveUI;using System;using System.Collections.Generic;usin...
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
well, uhh
gg, then, I guess
do I have it wrong?
this should be
List<Difficulties>
, should it not?
certainly, the list itself shouldn't be null
and it shouldn't includenull
within the list, right?it's not null. I removed the
?
'sk
trick...
also, generally, enum names should be singular
I.E.
Difficulty
not Difficulties
except if it's a Flags
enumso these are now these
GameType
versus GameTypes
and as a side note, I would probaly argue that PreviousQuestions
and BackButton
should not be in there
or else GameType
should be renamed to better reflect what it's purpose is
like PreviousQuestions
isn't really a "type" of game
it's what you're calling a different page in your app
an additional note
you can cheat a little bitso much to change it's getting a bit overloading. It's not you it's me
ok so I have these
I have this
if you do this....
with the explicit number definitions
you can make the RNG stuff a lot easier
I'm just going to start from the beginning
if you want to
what do I have wrong here
that seems a bit silly from here
looks fine to me
ok main window
ignoring the stuff that's commented out
what is
Database()
here?
it's not an ACUTAL database, is it?my database System.Data.SQLite
is there an
SqLiteConnection
in there?haven't shown the database file yet
you have not
I was taking it one file at the time
for my brains sake. here comes the database file
and the github service for the update
okay, that all looks fine
except for the liberal use of
static
what do you use github for?I have removed all static from the database file
self-updating?
when the application launches, it checks the github repo for the latest release, and if there is a release that is newer than the version that is in the
version.txt
file, then it prompts the user that there is an update and asks if they want to updatemm-kay
bit cheaty, but it works
that's the only way I learned how to build an updater into my project. The installer project hasn't been built into this project yet.
but the GithubServices pulls tid bits of info from the api call, and returns it for the program to know what to do and when. If the version.txt in the version that user has says
v1.0.2
and I've pushed a release to the github for v2.0.1
then it'll alert the user that an update is availabe and ask if they want to update which is done hereyou'd probably be better off encoding the version into the assembly itself
instead of a text file
I don't know where/how I would do that. I did the file because when I'm re-publishing the application, I'll think to myself "fuck I forgot to update the version" and it'll remind me to go to the file and update it then re-publish the app
Stack Overflow
How can I get the assembly file version
In AssemblyInfo there are two assembly versions:
AssemblyVersion: Specify the version of the assembly being attributed.
AssemblyFileVersion: Instructs a compiler to use a specific version number f...
how is that going to know the version of my application?
the version is baked into the assembly
where though?
like what file?
with an attribute attached to the assembly
which is generally applied within an
AssemblyInfo.cs
fileok I don't know what assembly means
Stack Overflow
C#: how to set version number of assembly
I have written a DLL in C# using VS2005.
Currently the DLL is showing a version number of 1.0.0.0. How do I set this version number to something different?
Currently the DLL is showing a version number of 1.0.0.0. How do I set this version number to something different?
"Assemby" is "the thing your program compiles to"
the DLL or EXE file
I don't have that in my file explorer in visual studio so how do I access it?
it's a file
add it
make it whatever you want
or put it in an existing file
AssemblyVersion
is an attribute you attach to the asembly, which is code
you can put it anywhere
what's the difference in that and me having the version.txt file?
like what makes that better?
txt file is a little more fragile
what if the file is missing?
or if someone messes with it?
ok I'm with you on that
I made an AssemblyInfo.cs file so what do I do with it?
I already told you
put the code in it
I did and that's what it told me
okay
and I put that file in the root of the game project itself not the root of the whole project since I'll be adding in a second project for the installer
right, that's correct
within the project, not the solution
right
so how come it's giving me a duplication error when that's the only file with that code that I believe I have?
because that's not the only file with that code
I double clicked my project
and I'm not seeing another file that would cause the dupe
yea I do
app.manifest
sweet
:/
so if it has it there, then I don't need the cs file. I can just do it here then
that's interesting
yeah
I guess that's an Avalonia thing
sort of
I mean, the app.manifest file is a requirement if you want to deploy to the Windows store
I doubt I'll ever do that honeslty lol
not sure if it's relevant for you deploying manually
what's probably happening then is Avalonia is automatically generating a
.cs
file from that XML, with the AssemblyVersion
attribute in itso here where I call the version file, I would replace that?
you can right-click on
AssemblyVersion
where you had it written and click "Find All References" and see
more like you would get rid of what, and wherever you have the code that reads from that file, you'd read from the assembly instead
via what I linked earlieroh I already deleted that cs file
I was just going to use the version in the app.manifest
you'll find that much more difficult to read
and also, that's not guaranteed to be there, same as the txt file
like, parsing that out of XML is doable, but it's cumbersome compared to a one-line reflection call
ok so I put the AssemblyInfo.cs file back
no
sure. I deleted it
Stack Overflow
How can I get the assembly file version
In AssemblyInfo there are two assembly versions:
AssemblyVersion: Specify the version of the assembly being attributed.
AssemblyFileVersion: Instructs a compiler to use a specific version number f...
so what specifically do I need to do
so I'm guessing I need to make the entire class static?
no
you need to move logic into methods
in this case, the constructor
or just
get rid of those fields
the public record version datat too?
that's not logic
that's a class definition
there's no need for it to be any more complicated than that
ok so now that is set to be the VersionData's current version
ok here's where I'm at so far
my first problem is the bool check
data.TagName != version
=> can't do thatwhy not?
Operator != cannot be applied to operands of type string and FileVersionInfo
and what does that mean?
I don't know how to fix that because the Tag Name that is pulled from the api call is a
[JsonPropertyName("tag_name")]
and is a string when it comes from the api
FileVersionInfo Class (System.Diagnostics)
Provides version information for a physical file on disk.
what do I do with that
read it
so I can do
string vName = version.FileVersion;
and fix itpossibly
they're strings, so that doesn't guarantee that they'll be the same value, when they represent the same version
if the documentation doesn't specify what
FileVersion
looks like, you'll want to test and make sure
in theory, it's just going to return whatever string you gave to [AssemblyVersion()]
so as long as you use the exact same string as the tag in github, it'll workwhen I hover over it to read it's snippet, it shows it as a string
I can do 1.0.0.0 instead of v1.0.0 for my release names. That's not a problem
oh
actually
okay, so there's a bit of nuance here
there's actually three different version IDs you can attach to your assembly
AssemblyVersion
, AssemblyFileVersion
, and AssemblyInformationVersion
each of those is retrieved slightly differentlywhich one do I need because in the app.manifest it has
<assemblyIdentity version="1.0.0.0" name="MeksMathGame.Desktop" />
and I thought that's what we were working withthat one refers to
AssemblyVersion
at least, that's what you told me
looks like best practice is actually to use AssemblyFileVersion
for deploymentsok so then how do I use that
the code you've got for retrieving the version is right
for setting it...
I'm so lost
how so?
app.manifest
right
that has an
assemblyIdentity
tagthis should pull that version number
no
it doesn't
that's what I'm saying
you said earlier that
assemblyIdentity
in app.manifest
was the cause of your duplicate AssemblyVersion
error
presumably, that XML file is source-generated into a .cs file that has that version
value in an AssemblyVersion
attribute
what you should possibly actually set and use for deployments is AssemblyFileVersion
ok wait
that's my bad
wait
it's in the Debug > net7.0 folder. that's why didn't see it
that's the duplication cause
right
as it says
auto-generated
now, we can see that
AssemblyFileVersionAttribute
and AssemblyVersionAttribute
are both thereright
Generated by the MSBuild WriteCodeFragment class.is that a class you have?
not that I'm aware of. I didn't create it if that's what you're asking
it likely came pre-gen'd with the framework when I created the project
if you change the value in
app.manifest
do the values in this generated file change?I don't know. I have errors in all of my other files that we've been working on fixing that I can't rebuild the project at this moment
check your .csproj file, are they set there?
no
mm-kay
well, I'll wager they're being set from the app.manifest, then
put a pin in that, I guess
ultimately, just make sure the versions are gonna match
I can try but if I don't know where to set them then I don't know how to update them to make them match
pulls the file version
pulls the assembly version
so change it in my github service to this Assembly.GetExecutingAssembly().Version
whichever you want to use
so long as you're consistent
so the full line is what?
var version = FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Version);
?
oh wait
no I misunderstood
here's what I haveokay
so since we changed the Game model from difficulty and game type of being strings to enum's, when I read that information from the database, how am I supposed to do it?
right now, Difficulty and GaemType are giving errors that
Possible null reference argument for parameter 's' in 'int int.Parse(String s)'
uhm
no
i left these as-is
okay
when the table's for the database are created, the difficulty and game type are
VARCHAR(2048)
so since we're dealing with enums now instead of string, do I need to change that too? and how do I read it back from the database since I can't do the .ToString()
on the reader index?you've got two options
SQLite doesn't have any kinda special support for enum types, so you have to store them as one of the 5 types it DOES support, and do a conversion
A) keep them as VARCHAR, I.E. strings, and you can use
.ToString()
and Enum.Parse<T>()
ok I make them strings when they're written to the database
ok I'll try the enum.parse
Enum.Parse<T>()
you can use in the UI layer as well, if you had the opportunity, but it has to be an EXACT match
if you're only ever inserting into the database from .ToString()
then that's not a problem
option B)
cast to int
and store and retrieve as NUMBER
conversion is simpler in this case, it's just a plan cast both ways
since enums are already int
s under the hood
it's a liiiiiiiiiiiittle risky if you're not explicitly defining WHAT int value each enum has
so, probably go with the string versionI did this
so with doing that, I need to change the tables to be INTEGERS instead of VARCHAR
you can
if you want
both ways are valid
both have advantages and disadvantages
ok I'm struggling a bit to read it back from the database. I changed them to be set to integers, but it's casting that integer back from the db to match the enum
oh
it's not EnumParse<int>
it's Enum.Parse<Difficulty>
right
also
that's the
string
approach
if you're going to use INTEGER as the underlying typeI need to do int.parse
yes, but also no
you can just to
.ToInt32()
on the reader instead of ToString()
or something to that effect
yeah, it should actually be....reader["Difficulty"] doesn't have a .ToInt32() but I can wrap it in an Convert.ToInt32()
alternatively, just
((int)reader["Difficulty"])
(I think)right
you chose not to store them as strings
so then which one do I use because nothing I am trying is working
step back and asses your problem
what is the problem?
the same problem we've been working on the last 20 messages or so. reading it back from teh db
wait
my cmd doesn't have a command text so I'm not reading anything
I mean
true
but also unrelated to the immediate problem
reading it back from teh dbreading what?
you know what the problem is and so do I. I'm just trying to find the reason the thing won't convert or read it right
and the reason you can't find that is because you don't actually know what the problem is
you haven't thought it through, thoroughly
what are you reading?
the Difficulty column?
what type is that?
it's not anything. I don't have a database created yet. As stated earlier, it was changed from a varchar to an integer. That's already been established
so
it's an integer
how do you read an integer out of that reader?
nothing I'm trying is working so obviously I don't know. If you know then please share
you do know though
ok
because I already did share
also, you were doing it long before I showed up
I'm telling you that I cannot figure it out. EVERYTHING I have tried of what I have been doing is NOT working
there is a question on the table
I'm not asking you to try everything and get all the errors to magically disappear
I'm asking you to answer a question
a question whose answer I have in fact already given to you
ok well apparently I don't know what that is so I'm just stuck and it's just becoming more obviously that I'm not that intelligent so I'll just keep trying things until I figure it out or whatever
or
instead of flailing randomly
you could answer the question on the table
and what would that question be
how do you read an
int
out of an SqliteDataReader
?ok so as I have stated several times already but it apparently keeps getting missed. Everything that I have tried is not working. You stated that I've been doing it long before you showed up, which would be like
Id = int.Parse(reader["Id"].ToString()),
that, however, for the nth time, nothing I am doing is not working. So obviously either I've answered your question, haven't given a sufficient enough answer, or I just don't know how to answer the question at all which I don't understand how I haven't I'm starting to honestly get frustrated and it's not with you whatsoever. you're just trying to help, but I've answered that question multiple times alreadyId = int.Parse(reader["Id"].ToString())so, in fact, you do know? you have made very clear that "nothing I am doing is working" I can, in fact, read can you? because what I have made repeatedly clear is that you need to step back from trying to do EVERYTHING you don't solve problems by just randomly trying "everything" you think might work you identify the problem, and break it down into smaller solvable pieces that you can put together if you constantly try to solve "everything" you're going to get nowhere right now, we are working on reading data from the database and there are quite a few errors here so, we're going to pick one and focus on that we've been talking about the
Difficulty
column, so that's our focus
that's one single line of code
obviously this is wrong, and you can't see what the right solution is, so we're going to continue breaking it down
what is involved in reading the Difficulty column from the database?
well, it's an INTEGER in the database
so, how do we read integers?
or, as I suggested, two other possibilities
or
let's go with the one I know is correctI don't have this. I have
Difficulty = Enum.Parse<Difficulty>()
I don't care what you have
are we solving the problem or not?
what you have is wrong, why would you keep going back to it
we're trying to figure out what you NEED
part one of that is
now
we have an
int
what do we need to do with it?
we need to put it into Difficulty
what is Difficulty
?
it's a Difficulty
enum value
so, we nee to take an int
and convert it to Difficulty
how do we do that?
I mentioned earlier, enums are int
already, under the hood
all we need is a cast
notice how there is no Enum.Parse<>
anywhere in there?
that's because Enum.Parse<>()
is... for parsing
which we're not doing
because you chose to take option B of the two options earlier, the one where Difficulty is INTEGER in the database, rather than VARCHARif I would have known anything about doing it this way, I would have said so. I didn't know that this was a thing, although I've learned the basics and have been practicing with console based applications before attempting avalonia.
you did though
you just couldn't put the pieces together
which is fine
what's not fine is just throwing up your hands and calling yourself stupid
the way you work a problem you don't understand is by breaking it down
that allows you to identify pieces that you DO understand
and occasionally those that you don't
you already knew how to retrieve
int
values from the database
the fact that I suggested a better way to do it is doesn't change that
and I told you that you could do a cast to convert int
to an enum
if you don't know what casting is say that
"I don't know what casting is"since I have to convert it when reading it back from the database, do I need to do any conversions when writing it to the database?
or "I don't know how to cast an int to an enum"
that is a specific, solvable problem
I'm not sure what SQLite will do, by default, for enum values
I didn't say that because I thought I knew how to do it, and misunderstood. That is my fault and I'll take that
PLEASE focus on that point
about breaking down problems
that is the SINGLE MOST SIGNIFICANT skill that people here often lack, when they come for help
which is why I focus on it
instead of just handing out code
so, yeah, I dunno what SQLite will do by default, so you should be explicit
I understand that, and often times I try to do that and google and find solutions on my own before coming here for help. I typically treat this as a last resort
honestly, don't
I mean, don't come here FIRST
but we're more powerful than google
google can answer questions
we can help you understand what questions you need to ask
understandable
ok so now that the database has been situated, and the github service along with the app.axaml and it's cs file and the main window, I'd like to send the next pages
you got all the other columns changed over?
at least, GameType?
correct. Once we got the difficulty column handled, I applied the same directives to the game type
great
so, if you removed those two pages from
GameType
then you need to handle them some other way, yeah?
me, I would just make two separate commandswait removed what pages from
GameTypes
PreviousGames
and... whatever the other one wasoh back button
ok so you're back on the home screen view model now
I was a page before that with the page where the player selects/creates their user
I thought that's what you were referring to
you said next pages
yes so the order the program is setup si
1. game launches and checks for update => if update available goes to UpdateAvailableView/ViewModel
2. if no update available => launch SelectUser()
this part of the main window view model
since my database functions are no longer static, I've got to learn a new way of calling the database as in the SelectUserViewModel where I call for the list of usernames, it's not liking it
create an instance
it's telling me that for
CurrentUsers = Database.GetUsernames();
I need an object referenceright
make one
create an instance of database?
do I do that in the constructor?
or get one from somewhere else
that would be the most sensible place
either create it there, or inject it there
ok so now question
in my MWVM, I have a private instance of the database, and I have in the first function
_db = db;
but I never do anything with it. Can I use that? If yes, do I just need to pass it down through the functions parameters?yes
ok cool
general practice is to inject dependencies via constructor, but parameter injection is also valid
ok if I go the constructor route, what would that look like? I'm familiar with using parameters.
and I have come across another problem too
passing database through the parameter works for the first function, but when I need to use it ReturnNewUser where it writes the user to the database, I can't access it
so I'm going to guess that going the constructor route will fix that?
I have no idea how to put that into this
what part is confusing?
my
public SelectUserViewModel
is already a function that does stuff. If I change it to
and try to keep my code block attached to that, it's going errorokay
so
why would you get rid of everything that's already there, for that constructor?
do you not know what that lambda
=>
syntax isI don't? or at least I don't think I do. I didn't even use them in Python if I didn't have too because they were too confusing.
the lambda can actually be used for a handful of different things in C#
in this case
it's literally just shorthand
is semantically identical to
"lambda-bodied method"
ok but I have code that goes with that function, so how do I incorporate that into this. Trying to pass db to return new user through the reactive command is my current problem that I'm trying to break down
I mean, that works
it says that I can't convert
MeksMathGame.Models.User to System.Action
so that's what I'm trying to break down to figure out and solveoh, right
you could do one of two things
public ReactiveCommand<Unit, User> SendNewUser { get; }
this is the reactive command if that helps
this use of a lambda is an "anonymous delegate"
the compiler translates this into a method on the class
wow that simple lol
actually, in this case
it translates that entire lambda into its own class
because it has to "capture" that
db
value
something like
that's complicated lol
little bit
but it should look familiar
it doesn't to me. I don't know like the
@this
part. Like I've never dove that deep into the semantics of a languagethe
@
allows me to use reserved keywords for variable/parameter/whatever names
this
is a language keywordhttps://pastebin.com/dVQUQ1cc offset question, how does the axaml file for this screen look
I called the parameter
@this
because the value I'm going to pass for that parameter is this
just like I use
this.RaiseAndSetIfChanged();
fine, I guess?
right
I just wanted to ensure that I couldn't do something here that would be more efficient or like make sure I wasn't missing something with a binding that the view should be doing and the logic not be doing or something
this
is the keyword that refers to "the current instance of a class, upon which a method is executing"
there is
you want to do what the closure does
but betterthat makes sense
again, let's work the problem
you have a
ReturnNewUser()
method
it requires a Database
instance to make calls oncorrect
it also can't have parameters, otherwise it isn't compatible with
ReactiveCommand.Create()
I was told that the view model should handle writing new users to the database instead of the main window view model as it's specific to that screen and that the main window view model should only handle navigation
that sounds fair to me
oh I'm in left field. never mind
so
where do we get
db
from?it's through the parameter which we figured out here
no
we said we can't use the parameter
at least, we shouldn't
oh
I took it out for a reason
cause it makes the method incompatible with
ReactiveCommand.Create()
right you did say that
we have to get state into that method without a parameter
how do we do that?
hint: you're doing it already
constructor?
well, sort of
indirectly
ok if I'm doing it already, let me take a look
the constructor initializes state upon the class instance
and the method has access to the class instance
ok I'm not seeing it
within that method
where does
NewUser
come from?
it wasn't passed in as a parameterI know that I pass the database through the parameters of SelectUserViewModel and use it to call the usernames from the database
NewUser
is bound to a TextBox
on the view screen that captures the new username that the user enters if their username doesn't already exist in CurrentUsers
yes, but what is it?
how can you access it within the method?
a string instantiated within the constructor
well, that might be its value
it would be any number of strings "instantiated" by the view as well
and then used later as
what that IS is a property
an instance property
on the class
backed up by
_newUser
which is an instance field
on the classso do I need to do the same thing with database?
something like
something like exactly what I posted above, yes
whelp
skip the property
and absolutely skip the
RaiseAndSetIfChanged()
calllike that!😄
like that
I had to think about that one for a second lol
ok great. Do I have any other issues that I'm not immediately seeing?
¯\_(ツ)_/¯
well
make all those fields private
I do haev one that I know about
you should basically never have public fields
ok I did that
SelectedUsername = CurrentUsers.Count > 0 ? CurrentUsers[0] : "Create New User";
on this line. If there are no usernames in the database, then it's supposed to show that combobox's index[0] to be "Create New User" instead of "Select One". This corresponds to the database here
however, regardless to the state of usernames or not existing, it still shows "Select One". I'm thinking that I'm indexing wrong, but I could be wrong on thatyeah, I dunno
someone was in here not too long ago with another issue related to Avalonia's ComboBox, and I realized Avalonia's ComboBox has a really weird API
at least compared to WPF/UWP/etc.
oh ok. So I'll just put a pin in that for now
https://pastebin.com/L1qM8ARG
so I know I have some errors already to figure out, but it's back to the fact that I stored the difficulty and game type as integers in the database. In the ViewModel where I need to use those values, how do I properly convert?
and I'm at this part now too
my vote is just make separate commands
I did go back and change my fields to private
and then instead of
Game
you'd have a PreviousGamesViewModel
and... whatever GoBack
should doso get rid of these
uhhh
no
keep those
just
what does the
GameTypes
parameter accomplish?
that should just be Unit
ok so question. From what I was told, MWVM should handle the navigation, so would it be better to have those commands return a value back to the MWVM so that it can continue to handle navigation?
y'know, I honestly have never build an MVVM app with page-based navigation
nothing now. I've removed those and change to Unit's
I think a lot of folks delegate to something like a
NavigationService
that's constructor injected
so in your child VM, you'd do
and NavigationService
would have
and MainWindowViewModel
can subscribe to thatI honestly don't know anything about that. I've been doing the navigation the only way anyone has taught me and that's through the MWVM with the Observable.Merge()'s
me, I would probably just put that
NavigationRequested
event on the child VM itself
and have MainWindowViewModel
subscribe to it directly
maybe
your way with Observable.Merge()
is also fine, really
it all kinda amounts to the same thingif it's ok, I'd like to keep it that way. It's something that I understand. I would not mind to learn the other way though on the next application I do which will be a diary application
MainWindowViewModel
is responsible for displaying the current VM, and each current VM is responsible for signaling to the MainWindowViewModel
when a navigation to a new VM is needed
with the exception of a Back
navigationright and I do that through returning models
that should really be implemented with something like a stack in the main window
and my version of a back button that I've been doing is just returning a null model
that's not completely crazy
either way, the main window is responsible for keeping track of what the preivous VMs were, so it can go back to them
I'm not going to lie to you
taking the update screen for example. The user is presented with two buttons. Yes and No. If they click the No button, it returns null
No = ReactiveCommand.Create(() => { });
and returns a null model. to which the if statement checks that it's null and if so, then I just call the function that holds the Content
that the main window view model is looking for which is in that function via var vm = new ...();
uuhhhhhm
okay
so like with this screen, the HomeScreenViewModel, i'd do my back button the same way
so now that leaves my previous games button
ahhh, okay, so
MainWindowViewModel
is subscribing to BackButton
?correct
sounds good
I would say that
PreviousGames
needs to be its own View and ViewModel, separate from Game
cause it's not a game
it's a totally different page
yes?
or am I not understanding what that is?it is. I just haven't built that screen yet.
okay
last I saw, you were returning a
Game
for that
so, beyond that, I dunno what you mean by "now that leaves my previous games button"I was, however, since Previous Games isn't in the GameTypes, I can't use that anymore as GameTypes is no long a string
yup
ok let me see if I can explain what I'm after better. one sec
I have to figure out a way for the PreviousGames button to return some model that doesn't match
GameTypes
in order for the check to know that the user wants to view that pageah
so
vm.Play
returns what?yay that made sense lol
Game
?(really should be
GameViewModel
)game engine sounds cooler lol
PreviousGames
will return whatever you make for it
PreviousGamesViewModel
currently it's trying to return a game model, but it doesn't need to. I don't know how to return a model that I don't have a model for though
so, that means that
Observable.Merge<T>(vm.Play, vm.PreviousGames)
should return IObservable<object>
yes?but if I'm understanding my code correctly, it has to return a game model so that the model in the mainwindowviewmodel know's how to check it, right?
it has to return a game modelwhy?
I'm honestly not sure. I've either been returning the model that is needed on that screen, or returning a null model like I do with the back button
so that the model in the mainwindowviewmodel know's how to check itonly because you've written it that way step back again it should return what it should return
I'm sure that the model that is subscribed in the mwvm can be any type of model
forget what the upstream is, we'll figure that out
I didn't know I could return a view model like that
however
why not?
it's a method
make it return whatever you want
with this setup, how would I check if model == to a view model?
Game
and PreviousGamesViewModel
don't have any common ancestor
at least
other than object
so, Observable.Merge()
should resolve to return IObservable<object>
all this means is that model
here is now just object
so you have to check it to see what it is
so, better yet
so I'm waiting to see what you show, but in the interum, I'm trying to return the view model, but it's not liking it
well, yeah
you defined the
PreviousGames
command to return Unit
if there's no actual data you need to return then you should probably keep that
and you can do....
I like this better so I changed it to this. great idea btw
then you could break out GoBack as well
I like that idea too. So I'm still hitting a wall with getting this right in the HSVM.
what is the
GameTypes
parameter for, in ShowPreviousGames
?
also, why is that returning PreviousGamesViewModel
?oh
I Meant to remove that
what data does HSVM need to return to MWVM in order for MWVM to load up a "Previous Games" screen
I'm guessing with the new Do methods on the subscribe, it doesn't need to anymore so I can have it return a null model as well, yea?
Unit
yeah
I suggested returning PreviousGamesViewModel
based on you returning Game
from the other ones
thinking Game
was a View or ViewModel object
if it's just a plain data container telling MWVM which game to play, then by extension PreviousGames
doesn't need that
there's no data it needs to pass up to MWVM
only the fact that the PreviousGames
button was click
I.E. all it needs is Unit
so I'm guessing the two buttons on the view itself, Previous Games and Back Button, no longer need COmmandParameter either
yup
ok bet 😄
bed time
ok have a good night. I'm going to put this up as a pin for where to start again when we both come back. I'm heading to bed myself
so when I removed the
?
's from the items inside the Game model, it threw this massive error on the Do operation. The reason I removed them is because it said it couldn't convert int?
to int
so I removed the ?
from the items in the Game model, and it threw that error. I also tried only removing the ?
from the game model's total questions, and it threw the same error so starting point for when we get back again. Have a good nightok so right now I'm lost on how to get this fixed. I've tried applying a direct cast
SelectedTotalQuestion = (int)model.TotalQuestions
and that didn't work. I've tried going through each file that uses the TotalQuestions from the Game model and removing all the ?
's and that didn't work so I'm lostget what fixed?
with the changes we've made so far, in the
MainWindowViewModel
on this portion
on line SelectedTotalQuestions = model.TotalQuestions
I get the error Cannot implicitly convert type 'int?' to 'int'. An explicit conversion exists (are you missing a cast?)
so I thought, let me try doign SelectedTotalQuestions = (int)model.TotalQuestions
, but when I do that, I get the error Argument 1: cannot convert from 'System.IObservable<MeksMathGame.Models.Game>' to 'System.Reactive.COncurrency.IScheduler'
and so I removed the cast, and went to the game's model and removed the ?
from
but int doing that, I get the same error Argument 1: cannot convert from 'System.IObservable<MeksMathGame.Models.Game>' to 'System.Reactive.COncurrency.IScheduler'
again. So I thought, well let me go through all of the files that use the Game model and remove the ?
from all the TotalQuestion conversions, and that and it resulted in the same error again. So I'm lost at this point on trying to fix this issuewhat is
Game
?a model
for what?
I definitely don't need a screenshot of the exact code you just posted
I use it to create the game models that when games are finished, or like in the instance of the HomeScreenViewModel where I have the function
it creates a new game model to send back to the
MainWindowViewModel
to pass over to the game engine so that the game engine has access to that information as it's already been selected and doesn't have to be selected again
I also use them for data validation as wellso, it represents a completed game?
or a game that may or may not be completed?
yes when a game is completed, but it's built throughout the process from selecting the difficulty, number of questions to answer, and the game type selected to pass to the game engine
so
the second one
"yes when a game is completed" except no
so, does it make sense for a game, completed or otherwise, to not have an associated number of questions?
well, to me, it's a yes/no. It's started as an empty object. Then when the user is on the home screen, part of it's built: TotalQuestions, Difficulty, GameType and then that is pushed to the game engine where the user plays the game, and when the game is over, the rest is built afterwards
well
either way is valid
pick one
well the TotalQuestions is there for 2 reasons. 1) it's so the program knows how many questions to answer and 2) when the user goes to preview their previous games, it's also displayed there so that they can see how many questions they answered per game played. In the previous games played, it's also used to show the average score / total score possible
this one sounds much better so I'll go with this one
so, you want it to be nullable, or no?
none of the information stored within the model is going to be null at all when it's passed to the database to be saved
otherwise, I'm not entirely sure how to answer that question
okay, reverse the question
if you do allow for that value to be
null
, what does a null
mean?there's nothing there.
no
it's not a string. it's not an int. it's nothing
what semantic/business meaning are you giving to the value of
null
when I think null, I think empty. Like where it would usually expect a string, or an int, it gets nothing. Like telling someone you'll give them $5 but never do. It's nothing
I'm not asking about
null
but I could very well be wrong on the definition of null
I'm asking about
TotalQuestions
what does it mean for a game to have no "Total Questions" valueit doens't. The screen where the user selected the difficulty, the number of questions to answer, and then clicks a button for the game type is setup that the game type buttons are not enabled unless both a difficulty and the number of questions to answer are selected
so it's never null. it's never not answered
like it's a requirement to be answered otherwise they cannot progress past that screen
if there is no semantic reason for a game to not have a "Total Questions" value, then don't model it that way
model your data to match your requirements
so remove the
?
yes
ok I did that, but I'm still getting the error of game model versus IScheduler, to which I know you're aware
Score
for example, has a meaning for null
it means "the game hasn't completed yet"I honestly can remove all the
?
's from the game model altogether. they don't need to be nullablealthough, you could also model that with an
IsCompleted
flag, and keep Score
as just 0
initially
if that's what makes sense for the purpose of the model
if all of those values are semantically required for the thing that the model is modelingI do that with score in the game engine
okay
so, this specifically is meant to model a completed game
I would recommend renaming it
CompletedGame
for clarityok I did that and changed it in all files too
so now that we got the CompletedGame model situated, how can I go about figuring out how to solve this error?
which one?
don't pass a value of type
IObservable<CompletedGame>
to something that requires a value of type IScheduler
so then I have something wrong here and I don't know what
where?
I'm assuming it's off the vm.Play button. That's the only part of the GetGameInformation function in the MWVM that's throwing an error like that
stop working around the problem
work the problem
don't pass a value of type IObservable<CompletedGame> to something that requires a value of type ISchedulerwhat there requires a value of type
IScheduler
?I literally have no idea
great
let's find out
what's highlighted?
the entire vm.Play portion
so, that error applies to that entire expression
yes
what type is that expression?
vm.Play?
it's a reactive command
the expression
that's highlighted
Observable.Merge()
that's a method
and also not highlighted
I don't know
find out
sure. let me be scooby doo for a second
vm.Play is a reactive command
okay
.Do is an IObservable<CompletedGame> IObservable<CompletedGame>.Do<CompletedGame>(Action<CompletedGame> onNext)
true statement
ok great
I assume I still haven't answered the question
I mean
you kinda have
.Do()
is the last piece of that expression, right?yes
so, the expression returns
IObservable<CompletedGame>
referring to the error, that's what the compiler can't convert to IScheduler
so, what are we passing that expression to?the play button
no
the
.Do
expression is attach to vm.Play
yes
and the whole expression that's highlighted is being passed to what?
Obervable.Merge
what signature of
Observable.Merge()
is the compiler binding to?IObservable
that's a type
not a method signature
The Merge then? I don't know
Observable.Merge
is a method
what is its signature?
specifically, which of its many signatures is the compiler binding to?i don't know
what is a method signature?
public
no
that is an access modifier
a method signature consists of its name and parameter types
those are the things that the compiler uses to determine which method to bind a method invocation to
Observable.Merge()
has many signaturesmakes sense
the easiest way to tell what the compiler is thinking with regard to method binding (usually) is to hover over the method call
it should tell you which method signature it's currently trying to bind to
sometimes, this doesn't work, when an error is present, but it's the first thing you should check
but in this case, it's rather obvious what's happening, now that we look at
Observable.Merge
in that case, it's actually clueing you into the fact that the compiler can't find a good one
so it's not specifying a specific match
it says "+ 11 overloads"
it doesn't know which one to pick
at least, Intellisense doesn't
the compiler seems to be picking the one that takes an
IScheduler
as the first argument
so
which one do we WANT it to be picking?IObservable
IObservable
is a type
not a method signatureI don't know then
well
what are we trying to do with
Observable.Merge()
?use vm.play
uhhh
alright
I'll bite
use it how?
I don't know. I'm just tired of saying that I don't know.
so I gave a guess
don't guess
not knowing something is a solvable problem
specify what you don't know
so, you don't know why you want to call
Observable.Merge()
?idk about you, but I use it so that when the button is clicked on the corresponding vm, the mwvm knows what to do with that button clicked
right, but the command does that
the one that's bound to the button
because you've setup each command with an empty action, (
() => { }
), each one just emits the moment it's executed
so, subscribing to each command tells you when that button is clicked
what do we need Observable.Merge()
for?to merge the information or something from the subscribed vm back to the mwvm?
what information?
that comes from the button being clicked
specifically
multiple buttons
we want
Observable.Merge()
because we have 3 different commands we're trying to listen to
and more specifically, because it makes it easy to manage subscriptionsright
I mentioned, we don't need
Observable.Merge()
to subscribe to a command
we could do that with...
but that leaves dangling subscriptions
when play is clicked
the other two listeners are still active
that's memory that can potentially leak
or even a bug that could manifest later, if that VM is reusedunderstandable and we don't want that
by merging them together, and then putting
Take(1)
on the merged stream, it means that everything gets torn down as soon as any of those commands emits
so
what we're trying to do with Observable.Merge()
is merge together 3 different streamsbecause it takes the first item clicked
each one representing a button click
and then tears down all the subscriptions
Take(1)
tears down the Merge()
subscription after the first emission
and Merge()
tears down all of the merged subscriptions when the downstream tears down
so
we're trying to use Observable.Merge()
to merge 3 observables
which signature of Observable.Merge()
do we want to callIObservable
once again
IObservable
is a type
not a method signaturethen I don't know.
subscribe?
subscribe is..... no
why don't you know?
(not being critical, legit question)
which piece of the question is the part you don't understand?
which signature of Observable.Merge() do we want to call
you said this
indeed
with this
indeed
so I said this and I'm still wrong. so therefore I don't know
IObservable
is literally present in every single one of those signatures
we're trying to use Observable.Merge() to merge 3 observableswhich one of those overloads can we pass 3 observables to?
idk
which one is it?
does this let me pass 3 observables to it?
please do not ask me another question just so that I have to keep saying I don't know. I do not know that's why I didn't give an answer and stated
idk which one is it?
okay
so which one is it expecting to be?
or needs to be since the program can't figure it out for itself
Hey. If you have a moment, I would like to apologize. I was not very open minded and was being stubborn with the code which is something I am heavily working on and I'm sorry. You were only trying to help, and I should have been more understand of that. I do apologize, and hope there are no hard feelings?
A genuine apology is a hell of a lot more than I usually get, so yes, no hard feelings. I don't know what else I could ask for.
Thank you.
you're welcome. I just know that when I get frustrated with code, I get stubborn and beyond pissed off with it. I am really trying to work on this. As part of that working on it thing, I've decided to take on a much smaller project to learn Avalonia with instead. I'm building an address book.
that sounds great
thank you ❤️ so I do have a question for you if that's alright
WIth this being an address book, my first go to with displaying all the contacts was with a DataGrid, however, I don't like this because I allow the user to store at least 15 things per contact and that'll become overloading to view in this manor. I'm wanting to make it like the mobile phones are done and change it to where it just displays the first and last name sorted by last name first, then first name included if no last name is given like
however, I don't know how to go about doing that.
this is all I have for my home screen view model at the moment. How would I go about achieving this?
for starters, you definitely don't want this
you don't want to be swapping out the entire collection every time the set of contacts changes
you want to either
A) load the contacts up-front
or
B) publish changes to the collection as they occur, rather than have the View layer need to completely rebuilt itself each time
either way, it's pointless to have the
People
property implement change notification, as the collection object itself should never change
A)
or
B)
change it to where it just displays the first and last nameeither expose that as a property on a ViewModel for each contact, or implement an
IValueConverter
to format each ContactModel
into a string display name, according to whatever rules you want
me personally, I'd lean towards the latter
deciding how data is displayed in text form is a View layer concern
the ViewModel's concern is to model and present the data to be viewed
the fact that you want to combine two properties of the underlying data (First Name and Last Name) and display them together is, as the wording suggests, a "display" concernOk. I’ll give it my best shot later today when I get online. I may need help implementing that though. I’ve never done this before. Apologies
ok so I made this change. I now have
so since the People variable was changed from a
List<string>
to a readonly ReadOnlyObservableList<ContactModel>
does that mean I have to change the way that the contacts are pulled from the database and returned from the function call?possibly
really, what you need to do is define how you want to abstract-ify this
like, you need to solidify the whole concept of this UI
at least for me, maybe you have it in your head already
it looks like this UI is supposed to be displaying all of the contacts that exist
how do you intend the "New Contact" operation to work, from a high-level?
or maybe, a more core question, what do you intend to be the "source of truth" for this UI?
I could foresee 3 answers
A) The database
this would mean that when you create a new contact, you send it down to the database, and then pull it back up, in some fashion
with the limitations of SQL, it really rather means that every time you do some kind of update to the set of contacts, in the database, you re-query the whole set
SQL databases don't really have a mechanism for having the database issue notifications up to the higher layer
for a small enough dataset, there's really nothing terribly wrong with this
it's obviously inefficient to re-query data that you know you don't need to, but it does tend to keep your application logic simpler
B) The ViewModel
as in
when the ViewModel initializes, it loads all the contacts from the database, and then becomes the central point of responsibility for managing them
if a new contact is created, or an existing contact is updated, that's tracked FIRST in the ViewModel's collection of contacts, and then replicating those changes down to the database is a side-effect
and you trust yourself to implement everything correctly-enough to avoid the database and VM becoming out-of-sync
C) A Service Layer
This is basically the same as B) except you move the logic for loading, saving, querying, etc. all the contacts out into a separate shared "service", which could then be reused by multiple different Views and ViewModels
what makes the most sense to you?
I've updated the repo. https://github.com/mekasu0124/MeksPhoneBook What I ended up doing was using ItemsControl. With my FAQ Page, I did this:
FAQView.axaml: https://pastebin.com/HgEeTuvQ
I mean, same deal
don't do that
expose
IReadOnlyList<T>
or ReadOnlyObservableCollection<T>
or ObservableCollection<T>
and do not implement INPC for the property, regardless
if the collection cannot be loaded before or during initialization, use whichever of the two observable collections is appropriate
otherwise, the collection does not ever need to change, and implementing change notification for it is pointlessWas 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.hey do you have a moment for me to ask a question?
if you have a question, ask it
database file: https://pastebin.com/GYqZ9UF8
new shift entry: https://pastebin.com/uE3CiXdM
helper file: https://pastebin.com/2NPHJgGi
on the inital screen that loads for the user, I'm wanting to display totals. Right now I'm trying to work out getting the total hours worked from the database. Each new shift entry auto tallies and stores the total time for each shift logged. What I'm trying to achieve is pulling those total times from the database, and adding them up together to show on the initial screen. Right now I have
my problem is getting the times to add. I was able to get it to work on a repl.it like this
but I can't figure out how to loop through the list, pull the TotalTime and then add them.
I'm wanting to add the times up, and then return them as a string (or appropriate data type) in the
totalTime
variable on the initial screenyou're having trouble adding a list of time spans?
what's wrong with
GetTotalShiftTime
?my immediate thing is instantiating the total variable
TimeSpan totalTime;
oh, I see
and being able to add to it. I don't know how to instantiate a blank TimeSpan variable
same way you instantiate anything else
TimeSpan totalTime = new();
?that'll work
also
also
does nothing
you're awesome. thank you!
since I'm already getting my values in the database file, would it be more efficient to just sum my totals from here and return them then to have a function in the helpers file that does it?
uhhhhhhhhhhhhhh
not sure what you're asking
oh, I see
I think
you're asking whether you should roll your extension method into this query method
no
what you should ACTUALLY do is do this whole thing in SQL
instead of querying for and retrieving 100 records, retrieve 1
the database can do that? I don't have to parse and all that other jazz to add the times up? That's dope
if you're doing things right
do yourself a favor and read up on SQL basics
ok I'll look into that
none of the sql basics that I've found on google show anything to do with querying a SUM from the database. would you happen to have a link I can get?
John Doe
SQL Tutorial
SQL Aggregate Functions
This tutorial introduces you to the most commonly used SQL aggregate functions including AVG, COUNT, MAX, MIN and SUM functions.
tyvm