[UWP] [XAML]内存使用和StaticResource问题 [英] [UWP][XAML] Problem with memory usage and StaticResource

查看:85
本文介绍了[UWP] [XAML]内存使用和StaticResource问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


我正在使用MVVM灯创建我的第一个C#UWP桌面应用程序,我对内存使用和DataTemplates的问题很小。在Button.cs中有一个ObservableCollection可能有不同的对象< IExample>,如:圆形,正方形和其他...
根据该集合中的内容,应该显示正确的UI:




全屏图片
链接


MainPage.xaml:

< Page xmlns =" ; HTTP://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x =" http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local =" using:MvvmLight1"
xmlns:ignore =" http://www.galasoft.ch/ignore"
xmlns:d =" http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc =" http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:interactivity =" using:Microsoft.Xaml.Interactivity"
xmlns:core =" using:Microsoft.Xaml.Interactions.Core"
xmlns:local1 =" using:MvvmLight1.Model"
x:Class =" MvvmLight1.MainPage"
mc:Ignorable =" d ignore"
DataContext =" {Binding Main,Source = {StaticResource Locator}}">
< Page.Resources>
<! - 圆圈模板 - >
< DataTemplate x:Key =" CircleTemplate">
< StackPanel>
< TextBlock Text ="这是圈子的模板......"前景= QUOT;深红"的Horizo​​ntalAlignment = QUOT;中心">< / TextBlock的>
< ColorPicker x:Name =" myColorPicker" ColorSpectrumShape = QUOT;环" />
< / StackPanel>
< / DataTemplate>
<! - square的模板 - >
< DataTemplate x:Key =" SquareTemplate">
< StackPanel>
< TextBlock Text ="这是方形的模板......"前景= QUOT;绿色"的Horizo​​ntalAlignment = QUOT;中心">< / TextBlock的>
< ColorPicker x:Name =" myColorPicker" ColorSpectrumShape = QUOT;环" />
< / StackPanel>
< / DataTemplate>

< local1:TemplateSelector x:Key =" MySelector"
CircleTemplate =" {StaticResource CircleTemplate}"
SquareTemplate =" {StaticResource SquareTemplate}"
/>

< /Page.Resources>
< Grid>
< Grid.ColumnDefinitions>
< ColumnDefinition Width =" 1 *" />
< ColumnDefinition Width =" 2 *" />
< /Grid.ColumnDefinitions>
< Grid.RowDefinitions>
< RowDefinition Height =" *" />
< /Grid.RowDefinitions>
<! - buttons - >
< GridView ItemsSource =" {Binding ButtonsList}" Grid.Row = QUOT; 0" SelectedItem =" {Binding SelectedButton,Mode = TwoWay,UpdateSourceTrigger = PropertyChanged}">
< GridView.ItemTemplate>
< DataTemplate x:DataType =" x:String">
< Grid>
< Grid.ColumnDefinitions>
< ColumnDefinition Width =" 250" />
< ColumnDefinition />
< /Grid.ColumnDefinitions>
< TextBlock Text =" {Binding Name}"前景= QUOT;红色"
FontSize =" 15" Grid.Column = QUOT; 0" VerticalAlignment = QUOT;拉伸"的Horizo​​ntalAlignment = QUOT;中心" />
< / Grid>
< / DataTemplate>
< /GridView.ItemTemplate>
< / GridView>

<! - properties - >
< ItemsControl ItemsSource =" {Binding InternalObjects,Mode = TwoWay,UpdateSourceTrigger = PropertyChanged}" ItemTemplateSelector =" {StaticResource MySelector}" DataContext =" {Binding SelectedButton}" Grid.Column = QUOT 1 QUOT;>< / ItemsControl的>
< / Grid>




Buttons.cs:

使用GalaSoft.MvvmLight; 
使用System.Collections.ObjectModel;

namespace MvvmLight1.Model
{
public class Button:ObservableObject
{
public string Name {get;组; }

public const string InternalObjectsPropertyName =" InternalObjects" ;;
private ObservableCollection< IExample> _internalObjects = null;
public ObservableCollection< IExample> InternalObjects
{
get
{
return _internalObjects;
}

set
{
if(_internalObjects == value)
{
return;
}

_internalObjects = value;
RaisePropertyChanged(InternalObjectsPropertyName);
}
}

public Button()
{
InternalObjects = new ObservableCollection< IExample>();
}
}
}

MainPageViewModel.cs

公共类MainViewModel:ViewModelBase 
{
public const string ButtonsListPropertyName =" ButtonsList" ;;
private ObservableCollection< Button> _buttonsList = null;
public ObservableCollection< Button> ButtonsList
{
get
{
return _buttonsList;
}

set
{
if(_buttonsList == value)
{
return;
}

_buttonsList = value;
RaisePropertyChanged(ButtonsListPropertyName);
}
}

public const string SelectedButtonPropertyName =" SelectedButton" ;;
private Button _selectedButton = null;
public Button SelectedButton
{
get
{
return _selectedButton;
}

set
{
if(_selectedButton == value)
{
return;
}

_selectedButton = value;
RaisePropertyChanged(SelectedButtonPropertyName);

}
}

public MainViewModel()
{
ButtonsList = new ObservableCollection< Button>();

//创建新按钮
for(var i = 0; i< 12; i ++)
{
ButtonsList.Add(new Button());
}

//少数人添加圈子...
for(var i = 0; i< 3; i ++)
{
ButtonsList [i] .Name ="带圆圈的按钮";
ButtonsList [i] .InternalObjects.Add(new Circles(){Name =" Circles"});
}
//为另一个添加方块...
for(var i = 3; i< 6; i ++)
{
ButtonsList [i]。 Name ="带有Squres的按钮" ;;
ButtonsList [i] .InternalObjects.Add(new Squares(){Name =" Squares"});
}
//其余的混合...
for(var i = 6; i< 12; i ++)
{
ButtonsList [i]。 Name ="带圆圈和方形的按钮";

ButtonsList [i] .InternalObjects.Add(new Circles(){Name =" Circles"});
ButtonsList [i] .InternalObjects.Add(new Squares(){Name =" Squares"});
}
}


}




Circles.cs Squares.cs:

公共课圈子:IExample 
{
public string Name {get;组; }
}


公共类Squares:IExample
{
public string Name {get;组; }
}

TemplateSelector.cs:

 public class TemplateSelector:DataTemplateSelector 
{
public DataTemplate CircleTemplate {get;组; }
public DataTemplate SquareTemplate {get;组; }
protected override DataTemplate SelectTemplateCore(object item)
{

if(item.GetType()== typeof(Circles))
{
return CircleTemplate;
}
else if(item.GetType()== typeof(Squares))
{
返回SquareTemplate;
}
其他
{
返回null;
}
}

protected override DataTemplate SelectTemplateCore(object item,DependencyObject container)
{
return SelectTemplateCore(item);
}

}

我做错了什么?为什么内存从19mb增加到91mb?如何处置未使用的模板?


非常感谢任何提示/修复示例代码。










解决方案


首先,当您单击按钮时,代码会创建新的引用和新对象。所以内存增加了。一旦清除了对象的引用,就可以处置该对象。我注意到当你停止点击时内存减少了。这是预期的行为。


如需进一步说明,您的应用程序是崩溃还是例外?如果没有,这不是问题。通常我们不需要担心内存使用。垃圾收集将自动发生。但垃圾收集是懒惰的,只有在
感觉压力时才会发生。这意味着当应用程序运行时,如果有其他应用程序需要更多内存,它将开始收集。如果垃圾收集发生但内存没有减少,那将是一个问题。 


祝你好运,


Roy


Hi,

I'm creating my first C# UWP Desktop application using MVVM light and I have small problem with memory usage and DataTemplates. In Button.cs there is a ObservableCollection that may have different objects <IExample>, like: circles, squares and other... Depending what is inside that collection, proper UI should be shown:

Full Screen image here: link

MainPage.xaml:

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:local="using:MvvmLight1"
  xmlns:ignore="http://www.galasoft.ch/ignore"
  xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
  xmlns:core="using:Microsoft.Xaml.Interactions.Core"
  xmlns:local1="using:MvvmLight1.Model"
  x:Class="MvvmLight1.MainPage"
  mc:Ignorable="d ignore"
  DataContext="{Binding Main, Source={StaticResource Locator}}">
<Page.Resources>
    <!-- template for circle -->
    <DataTemplate x:Key="CircleTemplate">
        <StackPanel>
            <TextBlock Text="This is the template for circle..." Foreground="Crimson" HorizontalAlignment="Center"></TextBlock>
            <ColorPicker x:Name="myColorPicker" ColorSpectrumShape="Ring"/>
        </StackPanel>
    </DataTemplate>
    <!-- template for square -->
    <DataTemplate x:Key="SquareTemplate">
            <StackPanel>
                <TextBlock Text="This is the template for square..." Foreground="Green" HorizontalAlignment="Center"></TextBlock>
                <ColorPicker x:Name="myColorPicker" ColorSpectrumShape="Ring"/>
            </StackPanel>
    </DataTemplate>

    <local1:TemplateSelector x:Key="MySelector"
        CircleTemplate="{StaticResource CircleTemplate}"
        SquareTemplate="{StaticResource SquareTemplate}"
    />

</Page.Resources>
<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="1*"/>
        <ColumnDefinition Width="2*"/>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <!-- buttons -->
    <GridView ItemsSource="{Binding ButtonsList}" Grid.Row="0" SelectedItem="{Binding SelectedButton, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
        <GridView.ItemTemplate>
            <DataTemplate x:DataType="x:String">
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="250"/>
                        <ColumnDefinition/>
                    </Grid.ColumnDefinitions>
                    <TextBlock Text="{Binding Name}" Foreground="Red" 
                       FontSize="15" Grid.Column="0" VerticalAlignment="Stretch" HorizontalAlignment="Center"/>
                </Grid>
            </DataTemplate>
        </GridView.ItemTemplate>
    </GridView>

    <!-- properties -->
    <ItemsControl ItemsSource="{Binding InternalObjects, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" ItemTemplateSelector="{StaticResource MySelector}" DataContext="{Binding SelectedButton}" Grid.Column="1"></ItemsControl>
</Grid>


Buttons.cs:

using GalaSoft.MvvmLight;
using System.Collections.ObjectModel;

namespace MvvmLight1.Model
{
    public class Button : ObservableObject
    {
        public string Name { get; set; }

        public const string InternalObjectsPropertyName = "InternalObjects";
        private ObservableCollection<IExample> _internalObjects = null;
        public ObservableCollection<IExample> InternalObjects
        {
            get
            {
                return _internalObjects;
            }

            set
            {
                if (_internalObjects == value)
                {
                    return;
                }

                _internalObjects = value;
                RaisePropertyChanged(InternalObjectsPropertyName);
            }
        }

        public Button()
        {
            InternalObjects = new ObservableCollection<IExample>();
        }
    }
}

MainPageViewModel.cs

public class MainViewModel : ViewModelBase
{
    public const string ButtonsListPropertyName = "ButtonsList";
    private ObservableCollection<Button> _buttonsList = null;
    public ObservableCollection<Button> ButtonsList
    {
        get
        {
            return _buttonsList;
        }

        set
        {
            if (_buttonsList == value)
            {
                return;
            }

            _buttonsList = value;
            RaisePropertyChanged(ButtonsListPropertyName);
        }
    }

    public const string SelectedButtonPropertyName = "SelectedButton";
    private Button _selectedButton = null;
    public Button SelectedButton
    {
        get
        {
            return _selectedButton;
        }

        set
        {
            if (_selectedButton == value)
            {
                return;
            }

            _selectedButton = value;
            RaisePropertyChanged(SelectedButtonPropertyName);

        }
    }

    public MainViewModel()
    {
        ButtonsList = new ObservableCollection<Button>();

        // create new buttons
        for (var i = 0; i < 12; i++)
        {
            ButtonsList.Add(new Button());
        }

        // for few of them add circles...
        for (var i = 0; i < 3; i++)
        {
            ButtonsList[i].Name = "Button with Circle";
            ButtonsList[i].InternalObjects.Add(new Circles() { Name = "Circles" });
        }
        // for another add squares...
        for (var i = 3; i < 6; i++)
        {
            ButtonsList[i].Name = "Button with Squres";
            ButtonsList[i].InternalObjects.Add(new Squares() { Name = "Squares" });
        }
        // rest of them mixed...
        for (var i = 6; i < 12; i++)
        {
            ButtonsList[i].Name = "Button with Circles and Squres";

            ButtonsList[i].InternalObjects.Add(new Circles() { Name = "Circles" });
            ButtonsList[i].InternalObjects.Add(new Squares() { Name = "Squares" });
        }
    }


}


Circles.cs and Squares.cs:

public class Circles : IExample
{
    public string Name { get; set; }
}


public class Squares : IExample
{
    public string Name { get; set; }
}

TemplateSelector.cs:

public class TemplateSelector : DataTemplateSelector
{
    public DataTemplate CircleTemplate { get; set; }
    public DataTemplate SquareTemplate { get; set; }
    protected override DataTemplate SelectTemplateCore(object item)
    {

        if (item.GetType() == typeof(Circles))
        {
            return CircleTemplate;
        }
        else if (item.GetType() == typeof(Squares))
        {
            return SquareTemplate;
        }
        else
        {
            return null;
        }
    }

    protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
    {
        return SelectTemplateCore(item);
    }

}

What am I doing wrong? Why memory grows from 19mb up to 91mb? How to dispose not used templates?

Many thanks for any hints/fixed example code.



解决方案

Hi,

First, when you click the button, the code creates new reference and new objects. So the memory is increased. Once the reference to an object is clear out, the object well be dispose. I noticed the memory is reduced when you stop click. It is expected behavior.

For further explanation, does your app crash or give exception? If not, it's not a problem. Generally we do not need to worry about the memory use. The Garbage collection will happen automatically. But the Garbage collection is lazy, it only happens when it feels pressure. It means when if there are other apps that require more memory when your app is running, it will start to collect. If the garbage collection happened but the memory does not reduce, that will be a problem. 

Best regards,

Roy


这篇关于[UWP] [XAML]内存使用和StaticResource问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆