I can't get the value I selected from the picker in the viewmodel
I select a value from the Picker. I see that it changes in the OnPropertyChanged() method in my ViewModel, but the value I select in the Task creation method is reset
43 Replies
Please post full source files, not little snippets. You may know how the different snippets tie together, but we have no idea
Hi
These are my taskviewmodel
Hi
Can you post as text files, rather than images of text?
The images are blurry, I can only look at one at a time, and I can't search them
Ok
I am attaching the following code where I have updated a list of collections (ObservableCollection), in the form of an array, to be able to store each Int32 element. Additionally, I have added a method to allow us to select each Int32 element.
public class ParentViewModel
{
public CustomerViewModel CustomerViewModel { get; }
public ProjectViewModel ProjectViewModel { get; }
public ActivityViewModel ActivityViewModel { get; }
public CategoryViewModel CategoryViewModel { get; }
public TaskViewModel TaskViewModel { get; }
public ParentViewModel()
{
var httpClient = new HttpClient { BaseAddress = new Uri("https://localhost:7017/") };
CustomerViewModel = new CustomerViewModel(new CustomerRepository(httpClient));
ProjectViewModel = new ProjectViewModel(new ProjectRepository(httpClient));
ActivityViewModel = new ActivityViewModel(new ActivityRepository(httpClient));
CategoryViewModel = new CategoryViewModel(new CategoryRepository(httpClient));
TaskViewModel = new TaskViewModel(new TaskRepository(httpClient));
}
}
}
And u can modify xaml code like this:
And what's the problem, exactly? I can't see any code which reads
NewPriority
, but you said that it's "reset" in "the Task creation method"?I am getting data from several viewmodels in the View, so I connected it to the parent viewmodel
And when I select the priority value from the Picker, I see that the value changes in onpropertychanged, but the NewTaske priority is 0.
U need to have
OnPropertyChanged()
on every ObservableCollectionIf I connect my Priority view directly to the taskviewmodel, my problem is solved, but this time the other picker objects in my view cannot receive the objects they receive from other viewmodels.
Only if it's assigned. ObservableCollections often aren't assigned
Oky
I don't see
NewTaske
anywhere in your code?private int _newPriority;
public int NewPriority
{
get => _newPriority;
set {
if (_newPriority != value)
{
_newPriority = value;
Console.WriteLine($"NewPriority updated to: {_newPriority}");
OnPropertyChanged();
}
}
}
Here comes the value when I change the priority
private async Task AddTaskCommandAsync()
{
var newTask = new TaskItem
{
TaskName = this.NewTaskName,
TaskDescription = this.NewTaskDescription,
TerminTime = IsTerminSelected ? FullTerminTime : null,
Priority = NewPriority
};
Console.WriteLine($"New Task created: TaskName = {newTask.TaskName}, Priority = {newTask.Priority}");
await _taskRepository.CreateTaskAsync(newTask);
Items.Add(newTask);
NewTaskName = string.Empty; NewTaskDescription = string.Empty; NewTerminTime = null; IsTerminSelected = false; } But when it passes here, it resets the value
NewTaskName = string.Empty; NewTaskDescription = string.Empty; NewTerminTime = null; IsTerminSelected = false; } But when it passes here, it resets the value
Where is that code? I don't see that in any of the files you posted
here
Ah sorry, Discord didn't expand it properly
"If I connect my Priority view directly to the taskviewmodel" -- what exactly do you mean by that?
Why don't you make a model class where you add all the attributes and use it in the ViewModel so as not to fill the code with alms?
"alms"?
I have multiple ViewModels, and in the view where the Priority is located, data is being retrieved from multiple ViewModels. For this reason, I created a ParentViewModel to bind this view. If I directly bind the view containing the Priority to my TaskViewModel, my issue is resolved. However, in that case, the connection with the CategoryViewModel, which retrieves data for the category picker, is lost. I am using the ParentViewModel to fetch data from multiple ViewModels.
It's like this right now
ProcessPropertiesView.BindingContext = _parentViewModel;
But if i do this
ProcessPropertiesView.BindingContext = _taskViewModel;
It is solved but it should actually be connected to the parent
It is solved but it should actually be connected to the parent
Where did
_taskViewModel
come from? Who creates it?public partial class MainPage : ContentPage
{
private readonly TaskViewModel _taskViewModel;
private readonly ParentViewModel _parentViewModel;
public MainPage(TaskViewModel taskViewModel, ParentViewModel parentViewModel)
{
InitializeComponent();
_taskViewModel = taskViewModel; _parentViewModel = parentViewModel; // TextEditorView ve JobsListView için aynı ViewModel'i kullanıyoruz TextEditorView.BindingContext = _taskViewModel; JobsListView.BindingContext = _taskViewModel; ProcessPropertiesView.BindingContext = _parentViewModel; }
_taskViewModel = taskViewModel; _parentViewModel = parentViewModel; // TextEditorView ve JobsListView için aynı ViewModel'i kullanıyoruz TextEditorView.BindingContext = _taskViewModel; JobsListView.BindingContext = _taskViewModel; ProcessPropertiesView.BindingContext = _parentViewModel; }
It sounds like you've got 2 instances of
TaskViewModel
, one created by ParentViewModel
(which is the version you're setting NewPriority
one, and another created somewhere in a view, which is the one you're calling AddTaskCommandAsync
on
Yep there we go -- your second TaskViewModel
instance is being injected, presumably being created by DI
If your TaskViewModel
is being created by the ParentViewModel
, then don't create a second one thereNot resolved when deleting from ParentViewModel
"Then you did it wrong" 😛
It's really hard for me to work out what the problem is when you're drip-feeding the relevant information like this
Since the view depends on the parentviewmodel, shouldn't the taskviewmodel be created there?
I'll explain it more clearly then
Can I see the code which calls
AddTaskCommand
?I am building a project manager application, and on my main page, I am calling four views. One of these views is a ListView where tasks are displayed, and another is a view where I select task-related details such as priority, customer, and categories. The third view contains editors where I enter the task's name, date, and description. There's one more view, but we don't need to focus on that right now.
The view with the task list is bound to the TaskViewModel because it only retrieves task-related information. The view where I enter the task's name, description, and date is also bound to the TaskViewModel. However, the view where I select task-related information like priority, customer, and category is bound to the ParentViewModel because it needs to retrieve data from multiple ViewModels, such as CategoryViewModel for categories and CustomerViewModel for customers.
If I don’t bind the view where I set the priority to the ParentViewModel, the customer and category data won't be retrieved. I tried removing the TaskViewModel from the ParentViewModel, but the problem persists because my view is bound to the ParentViewModel, and if I remove the TaskViewModel, I can no longer access its functions.
The AddTaskCommand is bound to a button, and the button triggers the following code:
private async Task AddTaskCommandAsync()
{
var newTask = new TaskItem
{
TaskName = this.NewTaskName,
TaskDescription = this.NewTaskDescription,
TerminTime = IsTerminSelected ? FullTerminTime : null,
Priority = NewPriority
};
Console.WriteLine($"New Task created: TaskName = {newTask.TaskName}, Priority = {newTask.Priority}");
await _taskRepository.CreateTaskAsync(newTask);
Items.Add(newTask);
NewTaskName = string.Empty; NewTaskDescription = string.Empty; NewTerminTime = null; IsTerminSelected = false; } I think I found the cause of the problem. My button that triggers the AddTaskCommand is connected to the taskviewmodel. So when you press the button, it calls the taskviewmodel twice as you said.
NewTaskName = string.Empty; NewTaskDescription = string.Empty; NewTerminTime = null; IsTerminSelected = false; } I think I found the cause of the problem. My button that triggers the AddTaskCommand is connected to the taskviewmodel. So when you press the button, it calls the taskviewmodel twice as you said.
The AddTaskCommand is bound to a button, and the button triggers the following code:Can you share that XAML? Right, I as looking for that binding.
"is connected to the taskviewmodel" -- which taskviewmodel?
Since I am currently connecting it to the Parentviewmodel, I connected the bindings by saying taskviewmodel. Normally, I did not write taskviewmodel because that is the only viewmodel it is connected to.
This is the view where the task name and description are located and also the task add button is located.
The problem is that my buttons and the view where I set the priority are bound to different ViewModels. The view where I select the priority is in the ParentViewModel, which initializes the TaskViewModel. The view with the editors also initializes the TaskViewModel, and this causes a conflict.
If I connect all my views to the parentviewmodel, it will unnecessarily run other viewmodels every time. For example, where my editors are, it is enough to call only 1 viewmodel.
Ah, so:
Not resolved when deleting from ParentViewModelYou had somewhere else which was creating a third TaskViewModel?
TextEditorView.BindingContext = _taskViewModel;
JobsListView.BindingContext = _taskViewModel;
ProcessPropertiesView.BindingContext = _parentViewModel;
I was talking about this. Taskviewmodel is also called in ParentViewModel and if I delete taskviewmodel from parentviewmodel, this time priority view cannot access taskviewmodel functions.
public CustomerViewModel CustomerViewModel { get; }
public ProjectViewModel ProjectViewModel { get; }
public ActivityViewModel ActivityViewModel { get; }
public CategoryViewModel CategoryViewModel { get; }
public TaskViewModel TaskViewModel { get; }
public ParentViewModel()
{
var httpClient = new HttpClient { BaseAddress = new Uri("https://localhost:7017/") };
CustomerViewModel = new CustomerViewModel(new CustomerRepository(httpClient));
ProjectViewModel = new ProjectViewModel(new ProjectRepository(httpClient));
ActivityViewModel = new ActivityViewModel(new ActivityRepository(httpClient));
CategoryViewModel = new CategoryViewModel(new CategoryRepository(httpClient));
TaskViewModel = new TaskViewModel(new TaskRepository(httpClient));
}
When choosing a priority, the taskview model is called here
When I click the add task button in the view where my editors and buttons are located, it calls the taskviewmodel again.
I'm confused. I said to remove the instance which was injected into ParentView. And if you did that, it should mean that there's only one instance of TaskViewModel, anywhere?
So my previously selected priority specific taskview model is restarted
If I remove the TaskViewModel from the parentviewmodel, how will my priority view access the taskviewmodel?
I think it would be better if I made the view task part of adding Priority and categories in the same view and connected the whole view to the parentviewmodel.
Sirr, try to connect on project using VS CODE LIVE to see all classes
sorry for my english
U can use
Live Share
@canton7No, I'm not doing that with strangers
Assign that same instance of the TaskViewModel to the PriorityView's DataContext?
(If you go VM-first, there sorts of problems disappear btw. VM-first is built around parent VMs owning child VMs, and the views just hanging off that VM hierarchy)
@canton7 I solve this but now the views connected to the parentviewmodel and the view connected to the taskviewmodel where my tasks are displayed do not work synchronously
When I restart the application, I can see the task I added