C
C#3mo ago
Mustafa

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
No description
No description
No description
43 Replies
canton7
canton73mo ago
Please post full source files, not little snippets. You may know how the different snippets tie together, but we have no idea
Casianm8
Casianm83mo ago
Hi
Mustafa
MustafaOP3mo ago
These are my taskviewmodel
No description
No description
Mustafa
MustafaOP3mo ago
Hi
canton7
canton73mo ago
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
Mustafa
MustafaOP3mo ago
Ok
Casianm8
Casianm83mo ago
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.
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Help
{
public class Test : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}




// It's used for Collection
private ObservableCollection<Int32> _Priorities = new ObservableCollection<Int32>();
public ObservableCollection<Int32> Priorities {
get { return _Priorities; }
set { _Priorities = value;
OnPropertyChanged(nameof(Priorities));
}
}

// It's used to select Int32 object from collection


private Int32 _Selected_Priorities;
public Int32 Selected_Priorities
{
get { return _Selected_Priorities; }
set { _Selected_Priorities = value;
OnPropertyChanged(nameof(Selected_Priorities));
}

}

public Test()
{
// Constructor

Priorities.Add(1);
Priorities.Add(3);
Priorities.Add(5);

foreach (var priority in Priorities)
{
Console.WriteLine($"Prioritate: {priority}");
}


}


}
}
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Help
{
public class Test : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}




// It's used for Collection
private ObservableCollection<Int32> _Priorities = new ObservableCollection<Int32>();
public ObservableCollection<Int32> Priorities {
get { return _Priorities; }
set { _Priorities = value;
OnPropertyChanged(nameof(Priorities));
}
}

// It's used to select Int32 object from collection


private Int32 _Selected_Priorities;
public Int32 Selected_Priorities
{
get { return _Selected_Priorities; }
set { _Selected_Priorities = value;
OnPropertyChanged(nameof(Selected_Priorities));
}

}

public Test()
{
// Constructor

Priorities.Add(1);
Priorities.Add(3);
Priorities.Add(5);

foreach (var priority in Priorities)
{
Console.WriteLine($"Prioritate: {priority}");
}


}


}
}
Mustafa
MustafaOP3mo ago
Mustafa
MustafaOP3mo ago
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)); }
}
Casianm8
Casianm83mo ago
And u can modify xaml code like this:
ItemsSource="{Binding Priorities, }"
SelectedItem="{Binding NewPriority, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
ItemsSource="{Binding Priorities, }"
SelectedItem="{Binding NewPriority, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
canton7
canton73mo ago
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"?
Mustafa
MustafaOP3mo ago
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.
Casianm8
Casianm83mo ago
U need to have OnPropertyChanged() on every ObservableCollection
Mustafa
MustafaOP3mo ago
If 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.
canton7
canton73mo ago
Only if it's assigned. ObservableCollections often aren't assigned
Casianm8
Casianm83mo ago
Oky
canton7
canton73mo ago
I don't see NewTaske anywhere in your code?
Mustafa
MustafaOP3mo ago
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
canton7
canton73mo ago
Where is that code? I don't see that in any of the files you posted
Mustafa
MustafaOP3mo ago
here
canton7
canton73mo ago
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?
Casianm8
Casianm83mo ago
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?
canton7
canton73mo ago
"alms"?
Mustafa
MustafaOP3mo ago
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
canton7
canton73mo ago
Where did _taskViewModel come from? Who creates it?
Mustafa
MustafaOP3mo ago
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; }
canton7
canton73mo ago
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 there
Mustafa
MustafaOP3mo ago
Not resolved when deleting from ParentViewModel
canton7
canton73mo ago
"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
Mustafa
MustafaOP3mo ago
Since the view depends on the parentviewmodel, shouldn't the taskviewmodel be created there? I'll explain it more clearly then
canton7
canton73mo ago
Can I see the code which calls AddTaskCommand?
Mustafa
MustafaOP3mo ago
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.
canton7
canton73mo ago
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.
Mustafa
MustafaOP3mo ago
canton7
canton73mo ago
"is connected to the taskviewmodel" -- which taskviewmodel?
Mustafa
MustafaOP3mo ago
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.
canton7
canton73mo ago
Ah, so:
Not resolved when deleting from ParentViewModel
You had somewhere else which was creating a third TaskViewModel?
Mustafa
MustafaOP3mo ago
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.
canton7
canton73mo ago
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?
Mustafa
MustafaOP3mo ago
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.
Casianm8
Casianm83mo ago
Sirr, try to connect on project using VS CODE LIVE to see all classes sorry for my english U can use Live Share @canton7
canton7
canton73mo ago
No, 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)
Mustafa
MustafaOP3mo ago
@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
Want results from more Discord servers?
Add your server