簡體   English   中英

正確處置用戶控件及其子級

[英]Correctly disposing user control and its children

我一直在尋找30分鍾以上,但是我根本無法弄清楚問題出在哪里。 我有一個TabControl ,它的項目將由用戶關閉。 由於每個TabItem都以某種方式連接到自定義控件和幾個對象,每個對象都占用大量內存,因此我想處置與此TabItem一起使用的所有對象。

為了使其更清楚並在簡化的情況下為您節省很多代碼:

<UserControl x:Class="myProject.GridFour"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">
    <Grid>
    <Grid.RowDefinitions>
        <RowDefinition />
        <RowDefinition />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>
        <ScrollViewer Height="Auto" Margin="0" Name="scrollViewer11" Width="Auto" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto"></ScrollViewer>
        <ScrollViewer Grid.Column="1" Height="Auto" Name="scrollViewer12" Width="Auto"  Margin="0" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto"></ScrollViewer>
        <ScrollViewer Grid.Row="1"> Height="Auto" Name="scrollViewer21" Width="Auto" Margin="0" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto"></ScrollViewer>
        <ScrollViewer Height="Auto" Name="scrollViewer22" Width="Auto" Grid.Column="1" Margin="0" Grid.Row="1" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto"></ScrollViewer>
    </Grid>
</UserControl>

現在,我設置相應選項的內容:

GridFour myControl = new GridFour();
myTabItem.Content = myControl;

我還有一些自定義對象,每個對象都包含一個網格,該網格作為內容添加到我的用戶控件的scrollviewer中:

class MyClass
{
    internal Grid _grid = new Grid();
    internal Image _image = new Image() {Width = Double.NaN, Height = Double.NaN HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center, Stretch = Stretch.Fill};
    //... a lot of variables, data, images and methods...
}

MyClass[] myObject = new MyClass[4];

for(int i = 0; i < 4; i++)
{
    myObject[i] = new MyClass();
    myObject[i]._grid.Children.Add(_image); //that actually happens when I initialise the object, it is just to show how everything is connected
}

myControl.scrollViewer11.Content = myObject[0]._grid;
myControl.scrollViewer12.Content = myObject[1]._grid;
myControl.scrollViewer21.Content = myObject[2]._grid;
myControl.scrollViewer22.Content = myObject[3]._grid;

現在,當用戶顯然想要關閉列表項時,我也想擺脫myControl和每個對象myObject。 我試圖通過IDisposable對其調用Dispose方法,但始終拋出NullReferenceException,我根本不知道為什么。

我也許應該提到,每個myObject都在Dictionary<string, MyClass>但是在調用dispose之前,我從那里刪除了該對象。

class MyClass : IDisposable
{ 
    internal Grid _grid = new Grid(); 
    internal Image _image = new Image() {Width = Double.NaN, Height = Double.NaN HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center, Stretch = Stretch.Fill}; 
    //... a lot of variables, data, images and methods... 

    public void Dispose()
    {
        // your custom disposing 
        _image = null; //or something like that
    }
}

因此,您要刪除UI元素,然后嘗試更新模型,而不是:

為什么不將UI綁定到對象的ObservableCollection列表。 然后要刪除,您只需要從模型中的列表中刪除(並根據需要進行處理)即可,但讓UI來完成它的工作,然后簡單地對列表進行更改即可。 這就是WPF最有效的方式。

這里一樣在TabControl.ItemsSource上閱讀

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM