Autor Beitrag
boskop
Hält's aus hier
Beiträge: 9



BeitragVerfasst: Di 16.12.08 10:15 
Hallo,

ich mache gerade erste Tests mit WPF und im Grossen und ganzen macht es mir einen sehr guten Eindruck. Was ich jetz aber nicht hinkriege ist folgendes:

Ich habe ein Window, wo ich ein paar Sachen anzeige. In diesem Window möchte ich auf Knopfdruck ein bestimmtes Panel austauschen, sprich das bestehende entfernen und durch ein neues ersetzen. Im Code läuft das auch gut durch... nur passt sich das Window nicht an. Wie muss ich das machen? :

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
  public partial class MainWindow : Window {
    public MainWindow() {
      InitializeComponent();
      ContentPanel.DataContext = new Person();
    }

    private void ChangePanelClicked(object sender, RoutedEventArgs e) {
      this.ContentPanel = new StackPanel();
      this.UpdateLayout();
    }
  }


Besten Dank für die Hilfe.

Moderiert von user profile iconChristian S.: Code- durch C#-Tags ersetzt
boskop Threadstarter
Hält's aus hier
Beiträge: 9



BeitragVerfasst: Di 16.12.08 12:03 
So... habs jetzt rausgefunden.

Ich muss auf dem Panel ein Clear() machen und kann es dann wieder mit neuem Inhalt füllen.

Aber weiss jemand, warum der Inhalt des Panels nach dem Clear() nicht Garbage Collected wird? Ich habe den Destructor der TextBox überschrieben und gebe es in der Konsole aus, wenn er aufgerufen wird.

ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
      ContentPanel.Children.Clear();
      ContentPanel.Children.Add(new OTextBox());
      ContentPanel.Children.Clear();
      ContentPanel.Children.Add(new OTextBox());
      ContentPanel.Children.Clear();
      Console.WriteLine(GC.GetTotalMemory(false));
      GC.Collect();
      GC.WaitForPendingFinalizers();
      Console.WriteLine(GC.GetTotalMemory(false));
      Console.WriteLine("*********************");


Hier wird beim Aufruf des GC nicht aufgeräumt. Erst, wenn ich die Applikation schliesse. Dann werden die 4 Instanzen von OTextBox aufgeräumt (2 Initial und 2 füge ich in der Methode hinzu und entferne sie wieder).

Dies gefällt mir nicht so ganz, denn wenn ich dies dynamisch und oft mache, habe ich ein Memoryleak. Muss ich das irgendwie anders machen?
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: Di 16.12.08 14:40 
Direkt in der selben Methode funktioniert das bei mir auch nicht (vielleicht hat der Render-Thread noch eine Referenz oder sowas), aber wenn ich es in einen Button-Click auslagere, wird bei weiteren Klicks immer das Control des vorherigen Klicks freigegeben.

_________________
>λ=
boskop Threadstarter
Hält's aus hier
Beiträge: 9



BeitragVerfasst: Di 16.12.08 15:26 
Ja das stimmt, aber in meinem Beispiel werden nur diejenigen, die ich in der Methode selber wieder hinzugefügt habe entfernt. Die, die initial im Panel waren, bleiben im Memory, wenn das GUI etwas komplexer ist:

ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
namespace WpfApplication1 {
  /// <summary>
  /// Interaction logic for Window1.xaml
  /// </summary>
  public partial class Window1 : Window {
    public Window1() {
      InitializeComponent();
    }


    private void button1_Click(object sender, RoutedEventArgs e) {
      ContentPanel.Children.Clear();
      Console.WriteLine(GC.GetTotalMemory(false));
      GC.Collect();
      Console.WriteLine(GC.GetTotalMemory(false));
      Console.WriteLine("*********************");
    } 
  }

  public class OTextBox : TextBox {
    ~OTextBox() {
      Console.WriteLine("destructor called.");
    }
  } 
}


ausblenden volle Höhe Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
<Window x:Class="WpfApplication1.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WpfApplication1"
    Title="Window1" Height="300" Width="300">
  <Grid>
    <Grid.RowDefinitions>
      <RowDefinition/>
    </Grid.RowDefinitions>
    <!-- Menu -->
    <DockPanel>
      <StackPanel DockPanel.Dock="Top">
        <Menu Height="24" Name="Menu" VerticalAlignment="Top" HorizontalAlignment="Stretch">
          <MenuItem Header="File">
            <MenuItem Header="Open" />
            <Separator />
            <MenuItem Command="ApplicationCommands.Stop" />
          </MenuItem>
          <MenuItem Header="Edit"></MenuItem>
        </Menu>
        <ToolBar Height="28" Name="Toolbar" VerticalAlignment="Top" HorizontalAlignment="Stretch">
          <Button Name="SaveButton">
            <Image Source="rsc/icons/Save.gif" />
          </Button>
          <Button Name="PrintButton">
            <Image Source="rsc/icons/Print.gif" />
          </Button>
        </ToolBar>
        <Button Grid.Row="4" Grid.Column="0" Click="button1_Click">Change Panel</Button>
      </StackPanel>
      <!-- OutlookBar -->
      <!-- ... -->
      <!-- Content -->
      <StackPanel DockPanel.Dock="Right" Name="ContentPanel">
        <!-- Bluebar -->
        <StackPanel Background="Blue" Orientation="Horizontal">
          <Label Foreground="White" Content="Person:" />
          <Label Foreground="White" Content="{Binding Path=ToString}"/>
        </StackPanel>
        <!-- Detail Panel -->
        <StackPanel>
          <ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Hidden">
            <Grid Margin="3,3,10,10" Name="FormPanel">
              <Grid.RowDefinitions>
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
              </Grid.RowDefinitions>
              <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition Width="*" />
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition Width="*" />
              </Grid.ColumnDefinitions>

              <Label Grid.Row="0" Grid.Column="0" Margin="3" >Name:</Label>
              <local:OTextBox Grid.Row="0" Grid.Column="1" Margin="3" />
              <Label Grid.Row="0" Grid.Column="2" Margin="3">Vorname:</Label>
              <local:OTextBox Grid.Row="0" Grid.Column="3" Margin="3" />

              <Label Grid.Row="2" Grid.Column="0" Margin="3">Grösse:</Label>
              <TextBox Grid.Row="2" Grid.Column="1" Margin="3" VerticalAlignment="Center" Height="Auto" />
              <Label Grid.Row="2" Grid.Column="2" Margin="3">Geburtstag:</Label>
              <TextBox Grid.Row="2" Grid.Column="3" Margin="3" VerticalAlignment="Center" Height="Auto" />

              <Label Grid.Row="3" Grid.Column="0" Margin="3">Strasse:</Label>
              <TextBox Grid.Row="3" Grid.Column="1" Margin="3" VerticalAlignment="Center" Height="Auto" />
              <Label Grid.Row="3" Grid.Column="2" Margin="3">Stadt:</Label>
              <TextBox Grid.Row="3" Grid.Column="3" Margin="3" VerticalAlignment="Center" Height="Auto" />

            </Grid>

          </ScrollViewer>
        </StackPanel>

      </StackPanel>
    </DockPanel>
  </Grid>

</Window>
boskop Threadstarter
Hält's aus hier
Beiträge: 9



BeitragVerfasst: Di 16.12.08 16:38 
So hab's gefunden. Das Problem ist folgende Zeile:

ausblenden Quelltext
1:
<Grid Margin="3,3,10,10" Name="FormPanel">					


Durch den Namen gibt es mir eine Instanzvariable im Window, was dazu führt, dass dieses Panel, wo meine OTextboxen drin sind nicht durch den GC verarbeitet wird.

Gruss

Boskop