Laden...

WPF - TabItem wird nicht richtig aktualisiert

Erstellt von bb1898 vor 8 Jahren Letzter Beitrag vor 8 Jahren 905 Views
B
bb1898 Themenstarter:in
112 Beiträge seit 2008
vor 8 Jahren
WPF - TabItem wird nicht richtig aktualisiert

Meine Testanwendung bewegt sich von einem Problem zum nächsten: Keine Fehlermeldungen im Entwurfsmodus mehr, aber beim Umschalten zwischen meinen beiden TabItems findet keine Aktualisierung statt. Genauer: sie wird im Fenster nicht sichtbar.

Das Hauptfenster hat das ViewModel KrimiVM; es enthält zwei UserControls: Listenanzeige und Detailseite. Listenanzeige hat ViewModel ListenanzeigeVM, Detailseite hat ViewModel DetailseiteVM.

KrimiVM hat

public ListenanzeigeVM Listen { get; private set; }
public DetailseiteVM Details { get; private set; }

public KrimiVM()
{
	Listen = new ListenanzeigeVM();
	Details = new DetailseiteVM();
}

Das bisschen "Geschäftslogik", das die Anwendung kennt, findet in der Klasse KrimiBAPI statt. Die implementiert INotifyPropertyChanged und hat unter anderem die Eigenschaft AktuellesBuch:


public BuchVM AktuellesBuch
{
	get
	{
		return _aktuellesbuch;
	}
	set
	{
		if (value != _aktuellesbuch)
		{
			_aktuellesbuch = value;
			RaiseChange("AktuellesBuch");
		}
	}
}

BuchVM ist eine triviale Verpackung der Modellklasse Buch und implementiert ebenfalls INPC.

Der Zugriff auf KrimiBAPI erfolgt über die Anwendungsklasse:

public partial class App : Application
{
	private static KrimiBAPI _bapi = new KrimiBAPI();

	public static KrimiBAPI BAPI
	{ get { return _bapi; } }
}

Die Klasse DetailseiteVM greift nur lesend auf App.BAPI.AktuellesBuch zu:

public BuchVM AktuellesBuch
{ get { return App.BAPI.AktuellesBuch; } }

In der Klasse ListenanzeigeVM wird diese Eigenschaft beim Wechsel des selektierten Listbox-Eintrags neu gesetzt.

Ein Ablaufverfolgungspunkt in der Loaded-Methode der Detailseite zeigt: Im ViewModel ist die Eigenschaft richtig, d.h. beim Wechsel in der Liste und anschließendem Umschalten auf die Detailseite enthält sie das ausgewählte Buch. Trotzdem zeigt die Detailseite immer das Buch an, das beim ersten Umschalten auf diese Seite aktuell war.

Die Detailseite besteht aus einem DataTemplate für die Buch-Details und zwei Schaltern:

<UserControl x:Class="OkCancel_Versuche.Detailseite"
    ... (xmlns wie üblich)
    xmlns:local="clr-namespace:OkCancel_Versuche"
    ...
    Loaded="UserControl_Loaded">
    <UserControl.Resources>
        <DataTemplate DataType="{x:Type local:BuchVM}">
            <Grid>
               ... (Details für ein Buch)
            </Grid>
        </DataTemplate>
    </UserControl.Resources>
    <DockPanel>
        <StackPanel DockPanel.Dock="Bottom" Orientation="Horizontal">
          ... (Schaltflächen)
        </StackPanel>
        <ContentControl Margin="5" Content="{Binding Path=AktuellesBuch}" />
    </DockPanel>
</UserControl>

Im Hauptfenster werden die UserControls so eingebunden:

<Window.Resources>
	<DataTemplate DataType="{x:Type local:ListenanzeigeVM}">
		<local:Listenanzeige />
	</DataTemplate>
	<DataTemplate DataType="{x:Type local:DetailseiteVM}">
		<local:Detailseite />
	</DataTemplate>
</Window.Resources>
<Grid>
	...
	<TabControl Grid.Row="1" SelectedIndex="{Binding AktuelleSeite}">
		<TabItem Header="Liste">
			<ContentControl Content="{Binding Listen}" />
		</TabItem>
		<TabItem Header="Details">
			<ContentControl Content="{Binding Details}" />
		</TabItem>
	</TabControl>
</Grid>

Ich vermute oder bin eigentlich fast sicher, dass ich mit dem DataTemplate in der Detailseite etwas falsch mache, bloß was?

301 Beiträge seit 2009
vor 8 Jahren

Spontane Frage ohne alles 2x gelesen zu haben :

public ListenanzeigeVM Listen { get; private set; }
public DetailseiteVM Details { get; private set; }

Die werfen kein RaisePropertyChanged ... warum genau nicht ?

B
bb1898 Themenstarter:in
112 Beiträge seit 2008
vor 8 Jahren

Spontane Frage ohne alles 2x gelesen zu haben :

public ListenanzeigeVM Listen { get; private set; }  
public DetailseiteVM Details { get; private set; }  

Die werfen kein RaisePropertyChanged ... warum genau nicht ?

Die werden im Konstruktor gesetzt und dann nie mehr ausgetauscht. Wenn sich ihre Eigenschaften ändern, ist dafür ja RaisePropertyChanged bei diesen Eigenschaften zuständig.

74 Beiträge seit 2014
vor 8 Jahren

Deine DetailseiteVM-Klasse muss natürlich auch PropertyChanged auslösen, sonst bekommt die GUI die Änderung nicht mit.

B
bb1898 Themenstarter:in
112 Beiträge seit 2008
vor 8 Jahren

Deine DetailseiteVM-Klasse muss natürlich auch PropertyChanged auslösen, sonst bekommt die GUI die Änderung nicht mit.

Genauer gesagt, die Eigenschaft AktuellesBuch in dieser Klasse braucht einen Setter, in dem PropertyChanged ausgelöst wird. Damit funktioniert es jetzt.