myCSharp.de - DIE C# und .NET Community
Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 
 | Suche | FAQ

» Hauptmenü
myCSharp.de
» Startseite
» Forum
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Suche
» Regeln
» Wie poste ich richtig?
» Forum-FAQ

Mitglieder
» Liste / Suche
» Wer ist wo online?

Ressourcen
» openbook: Visual C#
» openbook: OO
» Microsoft Docs

Team
» Kontakt
» Übersicht
» Wir über uns

» myCSharp.de Diskussionsforum
Du befindest Dich hier: Community-Index » Diskussionsforum » Entwicklung » GUI: WPF und XAML » Wie kann ich ein ItemsControl aktualisieren?
Letzter Beitrag | Erster ungelesener Beitrag Druckvorschau | Thema zu Favoriten hinzufügen

Antwort erstellen
Zum Ende der Seite springen  

Wie kann ich ein ItemsControl aktualisieren?

 
Autor
Beitrag « Vorheriges Thema | Nächstes Thema »
Davaaron
myCSharp.de-Mitglied

Dabei seit: 15.04.2016
Beiträge: 68


Davaaron ist offline

Wie kann ich ein ItemsControl aktualisieren?

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hi,

ich probiere mich mal etwas mit Prism aus und habe jetzt Regionen in WPF eingebaut.
Es gibt verschiedene Ansichten in der gleichen Region: Startansicht, Projektübersicht und Projekt erstellen.
Von der Projektübersicht gelangt man in die Ansicht "Projekt erstellen". Das Problem ist nun folgendes: Wenn ich ein Projekt erstelle (über Speicher-Button), dann sehe ich beim Debuggen im ViewModel der Projektübersicht auch das neue Projekt, die UI zeigt aber nur die alten Projekte an.
Ich dachte es liegt eventuell daran, dass Prism jedes mal ein neues VM erzeugt und die UI noch an das alte VM gebunden ist. Aber es wird nur ein Mal der Konstruktor meines VM aufgerufen.
Zudem habe ich das Problem, dass der Inhalt von der ProjectCardView (in XAMl von projectsOverviewView) leer ist.
Hier mal die relevanten Teile:

XAML: ProjectsOverviewView

XML-Code:
        <ItemsControl Grid.Row="3" ItemsSource="{Binding Path=ProjectCards}" Margin="20">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <viewscontrols:ProjectCardView DataContext="{Binding }"  Padding="15"></viewscontrols:ProjectCardView>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <WrapPanel/>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
        </ItemsControl>

C#-Code:
public class ProjectsOverviewViewModel : ViewModelBase<List<Project>>, IToolbarProvider, INavigationAware
    {
        private ObservableCollection<ProjectCardViewModel> _projectCards;



        private IRegionService _regionService;

        public ProjectsOverviewViewModel(IRegionService regionService)
        {
            _regionService = regionService;
            ProjectCards = new ObservableCollection<ProjectCardViewModel>();

            Init();
        }

        public ObservableCollection<ProjectCardViewModel> ProjectCards
        {
            get => _projectCards;
            set => SetProperty(ref _projectCards, value);
        }
        public ObservableCollection<ToolbarItemViewModel> ToolbarItems { get; private set; }
        public bool IsNavigationTarget(NavigationContext navigationContext)
        {
            return true;
        }

        private void Init()
        {

            InitCards();
        }

        private void InitCards()
        {
            ClientInfo.Workspace.Projects.ForEach(proj =>
            {
                ProjectCards.Add(new ProjectCardViewModel(_regionService)
                {
                    Name = proj.Name,
                    CreatedAt = proj.Created,
                    Modified = proj.Modified,
                    Model = proj
                });
            });
        }



        private void CreateNewProject()
        {
            _regionService.ChangeView<CreateProjectView>(RegionNames.MainContentRegion);
        }
    }

C#-Code:
public class CreateProjectViewModel : ViewModelBase<Project>
    {


        private void CreateProject()
        {
            Project newProject = new Project()
            {
                ID = Guid.NewGuid(),
                Created = DateTime.Now,
                Modified = DateTime.Now,
                Name = Name,
                Description = Description,
                Path = ClientInfo.ProjectsPath
            };
            try
            {
                var filename = Path.Combine(ClientInfo.ProjectsPath, newProject.Name + ".proj");
                newProject.Filename = filename;

                newProject.Workspace = ClientInfo.Workspace;
                ClientInfo.Workspace.Projects.Add(newProject);
                //Update model
                Serialization.SerializeDataContract(newProject, filename);
                Model = newProject;

                _regionService.ChangeView<ProjectsOverviewView>(RegionNames.MainContentRegion);

            }
            catch (Exception e)
            {

            }
        }
    }

Die Methode ChangeView<T>(string regionName) macht nichts besonderes:

C#-Code:
public void ChangeView<T>(string regionName, NavigationParameters parameters)
        {

            if (string.IsNullOrEmpty(regionName))
            {
                Trace.WriteLine("Cannot change view!");
                return;
            }
            var view = Provider.Resolve<T>();
            Debug.Assert(view.GetType().Name.EndsWith("View"));
            Navigate(regionName, typeof(T).Name, view, parameters);
        }

        public void Navigate(string regionName, string source, object view = null, NavigationParameters parameters = null)
        {
            if (parameters == null)
                RegionManager.RequestNavigate(regionName, source);
            else
                RegionManager.RequestNavigate(regionName, source, parameters);

            Trace.WriteLine($"Navigated {regionName} - {source}");

            if (view != null)
                OnChangedView?.Invoke(this, new ChangeViewEventArgs(regionName, view));
        }

Mit dem Tool Snoop sehe ich auch, dass die Daten eigentlich da sind... woran könnte es liegen?
Habe auch mal ein Bild hochgeladen mit den Snoop-Werten und der App. Diese Kacheln sind die ProjectCardsViews(Models).

Davaaron hat dieses Bild (verkleinerte Version) angehängt:
Inspection.png
Volle Bildgröße

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Davaaron am 09.11.2019 16:52.

09.11.2019 16:52 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
witte
myCSharp.de-Mitglied

Dabei seit: 03.09.2010
Beiträge: 826


witte ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Implementiert ProjectCardViewModel INotifyPropertyChanged?
09.11.2019 19:45 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Davaaron
myCSharp.de-Mitglied

Dabei seit: 15.04.2016
Beiträge: 68

Themenstarter Thema begonnen von Davaaron

Davaaron ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Ja, bzw. erbt BindableBas (von Prism, welches INotifyPropertyChanged implementiert).
Hab eben den ContentPresenter mal aufgeklappt und sehe, dass die Werte von der ProjectCardViewModel tatsächlich leer sind. Es scheint also einen Fehler beim Übertragen des Datenkontextes zu geben.
Ich gehe davon aus, dass die Zeile im XAML
"<viewscontrols:ProjectCardView DataContext="{Binding }" Padding="15"></viewscontrols:ProjectCardView>"
der ausschlaggebende Punkt ist.

Wenn es euch hilft, kann ich das Projekt auch gerne per .zip bereitstellen.

Edit: Ok, das Problem liegt doch daran, dass mir Prism jedes mal eine neue Instanz des ViewModels zurückgibt, wenn ich container.Resolve<T> aufrufe. Mal sehen, ob ich dies umgehen kann.
Denn das ist natürlich etwas doof: Zum Navigieren benutze ich den DI Container, um meine View zu bekommen. Dadurch wird dann aber ein ViewModel erzeugt. Die UI/View scheint aber an das alte ViewModel gebunden zu sein.

Edit2: Nein, daran liegt es nicht. Habe das ProjectOverviewModel nun als Singleton dem Container hinzugefügt (ich weiß, sollte man nicht machen): Selbes Verhalten.
Mein XAML für die ProjectOverviewView sieht nun so aus:

XML-Code:
<UserControl.Resources>
        <DataTemplate DataType="{x:Type vm:ProjectCardViewModel}">
            <viewscontrols:ProjectCardView DataContext="{Binding }" Padding="15"></viewscontrols:ProjectCardView>
        </DataTemplate>
    </UserControl.Resources>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="50"></RowDefinition>
            <RowDefinition Height="50"></RowDefinition>
            <RowDefinition Height="50"></RowDefinition>
            <RowDefinition Height="*"></RowDefinition>
        </Grid.RowDefinitions>
        <Label>Projects</Label>
        <Label Grid.Row="1" Content="{Binding }"></Label>
        <Label Grid.Row="2" Content="{Binding ProjectCards.Count, UpdateSourceTrigger=PropertyChanged}"></Label>

        <ItemsControl Grid.Row="3" ItemsSource="{Binding ProjectCards}" Margin="20">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <WrapPanel/>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
        </ItemsControl>
    </Grid>

Wenn ich für die ProjectCardView das DataContext entferne während der Laufzeit und wieder hinzufüge, dann werden die Cards mit Inhalt gefüllt (der Name, etc sind nun da).

Dieser Beitrag wurde 3 mal editiert, zum letzten Mal von Davaaron am 10.11.2019 00:39.

09.11.2019 23:27 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Davaaron
myCSharp.de-Mitglied

Dabei seit: 15.04.2016
Beiträge: 68

Themenstarter Thema begonnen von Davaaron

Davaaron ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Habe es gelöst. Letzten Endes war es nur eine Kleinigkeit: Ich habe jedes mal eine neue Liste erstellt in der Init Methode. Jetzt prüfe ich, ob die Liste null ist oder nicht. Demnach erstelle ich eine Liste oder füge die Elemente der bestehenden Liste hinzu.
Nun funktioniert alles wie erwartet und ich brauche auch keine Singletons mehr für die View, VM, etc.
10.11.2019 10:50 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Baumstruktur | Brettstruktur       | Top 
myCSharp.de | Forum
Antwort erstellen


© Copyright 2003-2019 myCSharp.de-Team | Impressum | Datenschutz | Alle Rechte vorbehalten. | Dieses Portal verwendet zum korrekten Betrieb Cookies. 15.11.2019 03:30