Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
Net Mau DataViewModel Picker zeigt aktuelle Auswahl nicht an
Toube
myCSharp.de - Member



Dabei seit:
Beiträge: 4

Themenstarter:

Net Mau DataViewModel Picker zeigt aktuelle Auswahl nicht an

beantworten | zitieren | melden

Hallo zusammen,

Ich hoffe ich bin im richtigen Forumsbereich mit meiner Frage gelandet.
Ich bin derzeit dabei eine Anwendung zu schreiben, bei welcher unter anderem mittels Picker ein "Parent" Item ausgewählt werden kann. Genau dieser Picker ärgert mich etwas.
Die Page hat als BindingContext als ViewModel, über diesen werden verschiedene Informationen unter anderem für den Picker bereitgestellt werden.

Was funktioniert:
ItemsSource zuweisen -> Mir wird mein Dropdown wie erwartet dargestellt
ItemDisplayBinding -> Name wird richtig dargestellt

Was nur teilweise funktioniert:
SelectedItem -> Das verändern des Wertes im Dropdown und anschließende speichern funktioniert wunderbar und wird korrekt in meine Datenbank im Hintergrund geschrieben. Wenn ich jedoch den Eintrag wieder "aufrufe" ist die Auswahl im Dropdown leer.

Ich hoffe ihr versteht soweit mein Problem und könnt mir der hoffentlichen Kleinigkeit helfen

relevante Page.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
......
    <ContentPage.BindingContext>
        <dataViewModels:CategoryViewModel/>
    </ContentPage.BindingContext>
    <Grid Margin="5">
......
        <Label Text="{x:Static s:strings.categoryNameLabel}" 
                Grid.Column="0"
                Grid.Row="0"/>
        <Entry  Text="{Binding Name}"
                Grid.Row="0"
                Grid.Column="1"/>
        <Label Text="{x:Static s:strings.categoryParentLabel}" 
                Grid.Column="0"
                Grid.Row="1"/>
        <Picker x:Name="ParentPicker"
                Grid.Row="1"
                Grid.Column="1"
                ItemsSource="{Binding ParentCategories,Mode=TwoWay}"
                ItemDisplayBinding="{Binding Name}"
                SelectedItem="{Binding Parent,Mode=TwoWay}"
                WidthRequest="200"/>
        <Button Text="{x:Static s:strings.saveButton}"
                Grid.Column="0"
                Grid.ColumnSpan="2"
                Grid.Row="2"
                Command="{Binding SaveCategoryCommand}"/>
    </Grid>
</ContentPage>

relevante Page.xaml.cs

using HouseholdSuiteCross.DataViewModel;
namespace HouseHoldSuiteCross.Views
{
	[QueryProperty(nameof(CategoryId),nameof(CategoryId))]
	public partial class CategoryPage : ContentPage
	{
		public int CategoryId
		{
			set
			{
				LoadCategoryAsync(value);
			}
		}

		public CategoryPage()
		{
			InitializeComponent();
		}

		public async void LoadCategoryAsync(int catId)
		{
            (BindingContext as CategoryViewModel).Model = await CategoryService.GetCategoryWithIdAsync(catId);
        }

		protected override async void OnAppearing()
		{
			base.OnAppearing();
			await (BindingContext as CategoryViewModel).UpdateParentCategories();
		}
	}
}

mein ViewModel:



namespace HouseholdSuiteCross.DataViewModel
{
    public class CategoryViewModel : BaseViewModel
    {
        private ObservableCollection<CategoryModel> _ParentCategories = new();

        private CategoryModel _model = new();
        //Public Properties
        public CategoryModel Model
        {
            get { return _model; }
            set
            {
                if(value != _model)
                {
                    _model = value;
                    OnPropertyChanged(nameof(Model));
                    OnPropertyChanged(nameof(Name));
                    OnPropertyChanged((nameof(Parent)));
                    OnPropertyChanged((nameof(NameParentCategory)));
                    OnPropertyChanged((nameof(CanSave)));
                }
            }
        }
        public string Name
        {
            get { return Model.Name; }
            set
            {
                if(Model.Name != value)
                {
                    Model.Name = value;
                    OnPropertyChanged(nameof(Name));
                    OnPropertyChanged((nameof(CanSave)));
                }
            }
        }
        public int Id
        {
            get { return Model.Id; }
        }
        public CategoryModel Parent
        {
            get
            {
                return Model.Parent;
            }
            set
            {
                if(Model.Parent != value)
                {
                    Model.Parent = value;
                    OnPropertyChanged((nameof(Parent)));
                    OnPropertyChanged((nameof(NameParentCategory)));
                }
            }
        }
        public ObservableCollection<CategoryModel> ParentCategories
        {
            get => _ParentCategories;
            set
            {
                if (ParentCategories != value)
                {
                    _ParentCategories = value;
                    OnPropertyChanged(nameof(ParentCategories));
                }
            }
        }

        public override void OnPropertyChanged(string propertyName)
        {
            base.OnPropertyChanged(propertyName);
            (SaveCategoryCommand as Command).ChangeCanExecute();
        }

        //Methods
        public async Task UpdateParentCategories()
        {
            List<CategoryModel>allCat = await CategoryService.GetAllCategoriesAsync();
            ParentCategories.Clear();
            foreach(CategoryModel category in allCat)
            {
                ParentCategories.Add(category);
            }
        }
    }
}
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Toube am .

Moderationshinweis von Abt (03.09.2022 - 15:25)

Bitte die richtigen Code Tags nutzen.

private Nachricht | Beiträge des Benutzers
Alf Ator
myCSharp.de - Member



Dabei seit:
Beiträge: 671

beantworten | zitieren | melden

Hallo Toube

Das sieht eigentlich ganz gut aus. Hast du eine Lösung gefunden?

Wenn nicht, vielleicht probierst du mal bei dem Picker sowas:

SelectedItem="{Binding Parent, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"

Gruß
Alf
private Nachricht | Beiträge des Benutzers
Toube
myCSharp.de - Member



Dabei seit:
Beiträge: 4

Themenstarter:

beantworten | zitieren | melden

Hallo Alf,
danke für deinen Hinweis.
Bei Maui scheint es kein
UpdateSourceTrigger
mehr zu geben.
Mode=TwoWay
habe ich ergänzt, leider hat es nicht zum Erfolg geführt.

Was ich noch ganz spannend finde:
Ich habe einen Versuch gestartet die Auswahl mittels Code zuzuweisen

	public async void LoadCategoryAsync(int catId)
	{
            (BindingContext as CategoryViewModel).Model = await CategoryService.GetCategoryWithIdAsync(catId);
			ParentPicker.SelectedItem = (BindingContext as CategoryViewModel).Parent;
        }

Das Feld bleibt beim Laden eines Items mit Parent immer noch leer.
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Toube am .
private Nachricht | Beiträge des Benutzers
Toube
myCSharp.de - Member



Dabei seit:
Beiträge: 4

Themenstarter:

beantworten | zitieren | melden

Folgende Veränderung führt zum Erfolg, zumindest mittels Code behind.


		protected override async void OnAppearing()
		{
			base.OnAppearing();

            var bindingContext = (BindingContext as CategoryViewModel);
            await bindingContext.UpdateParentCategories();

            if (bindingContext.Parent == null)
            {
                return;
            }

            foreach (var cat in bindingContext.ParentCategories)
            {
                if (cat.Id == bindingContext.Parent.Id)
                {
                    ParentPicker.SelectedItem = cat;
                }
            }
        }

Falls mir jemand noch erklären könnte weshalb es nicht im xaml klappt wäre super
private Nachricht | Beiträge des Benutzers
Toube
myCSharp.de - Member



Dabei seit:
Beiträge: 4

Themenstarter:

beantworten | zitieren | melden

Entgültige Lösung des Problems gefunden:
Ich hatte das SelectedItem auf dem public CategoryModel Parent gebunden gehabt.
Wenn ich in meinen ViewModel den Datentyp von CategoryModel auf den Datentyp CategoryViewModel umändere funktioniert es.

Problem ist gelöst
private Nachricht | Beiträge des Benutzers
Alf Ator
myCSharp.de - Member



Dabei seit:
Beiträge: 671

beantworten | zitieren | melden

Zitat von Toube
Problem ist gelöst




Das mit dem UpdateSourceTrigger ist ja interessant. Hatte ja seine Berechtigung.
Mode=TwoWay ist imho der Default-Wert.
private Nachricht | Beiträge des Benutzers