Dear Community!
I am confused with the Comboboxfield for the DataGrid. I want to use the List Usernames as the Datasource to pick from to the set the responsible person Property in the WorkDisplayViewModel class. However, as soon as i have picked a person and unfocus the Combobox, the Value is directly set to its original value again. Where does this come from? Secondly i wanted to display Enum values to choose for the Priority, however, i do not even get anything inside the Combobox for the enum values. What am i doing wrong?
The DataGrid:
<dataGrid:SfDataGrid.Columns>
<dataGrid:DataGridComboBoxColumn HeaderText="Responsible Person"
MappingName="ResponsiblePerson"
DisplayMemberPath="name"
ItemsSource="{Binding Usernames}"/>
<dataGrid:DataGridTextColumn MappingName="Description" HeaderText="Description"
CellTextAlignment="Center"
HeaderTextAlignment="Center"/>
<dataGrid:DataGridComboBoxColumn MappingName="Priority" HeaderText="Priority"
ItemsSource="{Binding Priorities}"
CellTextAlignment="Center"
HeaderTextAlignment="Center"/>
</dataGrid:SfDataGrid.Columns>
</dataGrid:SfDataGrid>
The ViewModel of the page:
public partial class VehicleDetailsViewModel : BaseViewModel
{
// == observable properties ==
[ObservableProperty]
private VehicleDisplayViewModel vehicle;
[ObservableProperty]
private ObservableCollection<VehicleDisplayViewModel> vehicleForDisplay;
[ObservableProperty]
private bool propertyUpdated;
[ObservableProperty]
private AddWorkModel workToAdd;
[ObservableProperty]
private ObservableCollection<UserNameResponse> usernames;
[ObservableProperty]
private bool isAddWorkPopupOpen;
[ObservableProperty]
private bool workChanged;
public IEnumerable<Priorities> Priorities { get; set; }
// == private fields ==
private VehicleTransferObject _vehicleTransferObject;
private readonly VehicleState _vehicleState;
private readonly UserState _userState;
private VehicleDisplayViewModel original;
private readonly WorkState _workState;
// == constructor ==
public VehicleDetailsViewModel(NavigationService navigationService, VehicleTransferObject vehicleTransferObject, VehicleState vehicleState,
UserState userState, WorkState workState) : base(navigationService)
{
Priorities = Enum.GetValues(typeof(Priorities)).Cast<Priorities>();
_vehicleState = vehicleState;
_workState = workState;
_userState = userState;
_userState.UserNamesReceived += (sender, list) => Usernames = new ObservableCollection<UserNameResponse>(list);
_userState.GetAllUsernames();
_vehicleTransferObject = vehicleTransferObject;
original = new VehicleDisplayViewModel(_vehicleTransferObject.VehicleDisplayViewModel);
_vehicleTransferObject.VehicleDisplayViewModel.PropertyChanged += VehicleDisplayViewModelOnPropertyChanged;
Vehicle = vehicleTransferObject.VehicleDisplayViewModel;
VehicleForDisplay = new ObservableCollection<VehicleDisplayViewModel>();
VehicleForDisplay.Add(Vehicle);
Vehicle.Works.ToList().ForEach(t => t.PropertyChanged += WorkPropertyChanged);
WorkToAdd = new AddWorkModel();
}
// == relay commands ==
[RelayCommand]
public async Task UpdateWorks()
{
List<WorkDisplayViewModel> toChange = Vehicle.Works.Where(f => !f.Equals(f.Original)).ToList();
await Task.WhenAll(toChange.Select(async t =>
{
await _workState.UpdateWork(t.Identifier, new WorkRequest()
{
description = t.Description,
priority = t.Priority,
responsiblePerson = t.ResponsiblePerson,
vehicleIdentifier = t.VehicleIdentifier
});
t.Original = new WorkDisplayViewModel(t);
await GetWorks();
}));
}
[RelayCommand]
public async Task OpenAddWorkPopup()
{
IsAddWorkPopupOpen = true;
}
[RelayCommand]
public async Task UpdateVehicle()
{
await _vehicleState.UpdateVehicle(Vehicle.Identifier, new VehicleRequest()
{
number = Vehicle.Number,
type = Vehicle.Type,
status = Vehicle.Status,
stand = Vehicle.Stand,
priority = Vehicle.Priority
});
PropertyUpdated = false;
}
[RelayCommand]
public async Task AddWork()
{
WorkRequest request = new WorkRequest()
{
description = WorkToAdd.Description,
priority = WorkToAdd.Priority,
responsiblePerson = WorkToAdd.ResponsiblePerson,
vehicleIdentifier = Vehicle.Identifier
};
await _workState.AddWork(request);
GetWorks();
}
// == public methods ==
public async Task GetWorks()
{
List<WorkDisplayViewModel> works = await _workState.GetWorksForVehicle(Vehicle.Identifier);
Vehicle.Works.AddRange(works.Where(t => Vehicle.Works.All( f => f.Identifier != t.Identifier)));
}
// == private methods ==
private void WorkPropertyChanged(object? sender, PropertyChangedEventArgs e)
{
if(sender is not WorkDisplayViewModel work)
return;
WorkChanged = Vehicle.Works.Any(f => !f.Equals(f.Original));
}
private void VehicleDisplayViewModelOnPropertyChanged(object? sender, PropertyChangedEventArgs e)
{
if(sender is not VehicleDisplayViewModel account || e.PropertyName is nameof(VehicleDisplayViewModel.WorkCount))
return;
bool equals = original.Equals(account);
PropertyUpdated = !equals;
}
}
The display viewmodel where i want to set the ResponsiblePerson Property:
ublic partial class WorkDisplayViewModel : BaseDisplayViewModel
{
[ObservableProperty]
private string vehicle;
[ObservableProperty]
private UserNameResponse responsiblePerson;
[ObservableProperty]
private string description;
[ObservableProperty]
private Priorities priority;
[ObservableProperty]
private string createdBy;
[ObservableProperty]
private string updatedBy;
[ObservableProperty]
private WorkDisplayViewModel original;
// == properties ==
public string VehicleIdentifier { get; set; }
// == constructor ==
public WorkDisplayViewModel(WorkResponse response)
{
Vehicle = response.vehicle;
VehicleIdentifier = response.vehicleIdentifier;
Identifier = response.identifier;
ResponsiblePerson = response.responsiblePerson;
Description = response.description;
Priority = response.priority;
CreatedBy = response.createdBy;
UpdatedBy = response.updatedBy;
Original = new WorkDisplayViewModel(this);
}
public WorkDisplayViewModel(WorkDisplayViewModel response)
{
Vehicle = response.Vehicle;
VehicleIdentifier = response.VehicleIdentifier;
Identifier = response.Identifier;
ResponsiblePerson = response.ResponsiblePerson;
Description = response.Description;
Priority = response.Priority;
CreatedBy = response.CreatedBy;
UpdatedBy = response.UpdatedBy;
}
partial void OnResponsiblePersonChanged(UserNameResponse? oldValue, UserNameResponse newValue)
{
Console.WriteLine("t");
}
// == override methods ==
public override bool Equals(object? obj)
{
if (obj == null || GetType() != obj.GetType())
return false;
var other = (WorkDisplayViewModel)obj;
return ResponsiblePerson == other.ResponsiblePerson &&
Description == other.Description &&
Priority == other.Priority &&
CreatedBy == other.CreatedBy &&
UpdatedBy == other.UpdatedBy;
}
}
And the corresponding class:
public class UserNameResponse
{
public string name { get; set; }
public string identifier { get; set; }
}
Hi Oliver ,
|
Query |
Response |
|
|
I am confused with the Comboboxfield for the DataGrid. I want to use the List Usernames as the Datasource to pick from to the set the responsible person Property in the WorkDisplayViewModel class. However, as soon as i have picked a person and unfocus the Combobox, the Value is directly set to its original value again. Where does this come from? |
As of now, DataGrid does not have support for binding User Defined collection in DataGridComboBox column. We have already considered your request as a feature. We will implement this feature in any of our upcoming releases. At the planning stage for every release cycle, we review all open features and identify features for implementation based on specific parameters including product vision, technological feasibility, and customer interest. We appreciate your patience and understanding until then. You can follow up with the below feedback for further details,
Feedback link: https://www.syncfusion.com/feedback/45786/provide-support-to-bind-user-defined-collection-in-datagridcombobox-column |
|
|
Secondly i wanted to display Enum values to choose for the Priority, however, i do not even get anything inside the Combobox for the enum values. What am i doing wrong? |
Based on the information provided, it appears that the issue you are experiencing is related to type conversion. To resolve this issue, you need to convert the ObservableCollection of enum to IEnumerable<object>. We have attached a simple sample and a code snippet for your reference.
Code snippet:
|
Regards,
Nirmalkumar
Oliver,
Please find the sample below.
Regards,
Nirmalkumar
I am a bit confused with the first answer you provided as the documentation explicitely states that i can use UserDefined types: "
To display a list of user-defined items in the drop-down of a combo box, create a DataGridComboBoxColumn and set its ItemsSource property to a user-defined collection. By default, if the DisplayMemberPath is not set, the combo box column will display the values from the MappingName property of the column."
And indeed when i select a specific value of the Combobox it is set correctly as the ResponsiblePerson, however, when i deselect the ComboBox again and select another column, for example, the value is automatically set to null again.
Hi Oliver,
We have previously provided
support for binding the User-defined collection in the Combo box column for the
UI. However, editing capabilities were not included in this support. We are
pleased to inform you that we have now implemented enhancements to meet your
requirements. These enhancements will be included in our upcoming weekly patch
release scheduled for February 20, 2024. We will notify you as soon as the
release is available, and we sincerely appreciate your patience in the
meantime.
Regards,
Nirmalkumar
Hi Oliver,
We are glad to inform you that the enhancement “Support to edit UserDefined collection in DataGridComboBoxColumn” has been included in our weekly NuGet release. Please update the Syncfusion.Maui.DataGrid package to version 24.2.7.
https://www.nuget.org/packages/Syncfusion.Maui.DataGrid
We thank you for your support and appreciate your patience in waiting for this update. Please contact us if you require any further assistance.
Regards,
Nirmalkumar