Wpf OnRenderSizeChanged是否未正确调用?
我有一个自定义画布,它应该用最大数量的平铺对象填充自己 如果将其大小调整为更大,则会用其他平铺填充空白空间。 如果将其大小调整为更小,则会删除不再可见的平铺 这只有在我调整的非常慢的情况下才有效,否则一切都会开始混乱 我肯定是做错了什么,下面的代码就是画布:Wpf OnRenderSizeChanged是否未正确调用?,wpf,Wpf,我有一个自定义画布,它应该用最大数量的平铺对象填充自己 如果将其大小调整为更大,则会用其他平铺填充空白空间。 如果将其大小调整为更小,则会删除不再可见的平铺 这只有在我调整的非常慢的情况下才有效,否则一切都会开始混乱 我肯定是做错了什么,下面的代码就是画布: using System; using System.Windows; using System.Windows.Controls; namespace WpfApplication1.View { public class
using System;
using System.Windows;
using System.Windows.Controls;
namespace WpfApplication1.View
{
public class TileCanvas : Canvas
{
#region Fields
private Boolean _firstCreation;
private Double _heightDifference;
private Double _widthDifference;
#endregion // Fields
#region Properties
public static readonly DependencyProperty TileSizeProperty =
DependencyProperty.Register("TileSize", typeof (Int32), typeof (TileCanvas),
new PropertyMetadata(30));
public Int32 TileSize
{
get { return (Int32) GetValue(TileSizeProperty); }
set { SetValue(TileSizeProperty, value); }
}
public Int32 Columns { get; private set; }
public Int32 Rows { get; private set; }
#endregion // Properties
#region Constructors
public TileCanvas()
{
_firstCreation = true;
}
#endregion // Constructors
#region Methods
#region Public
#endregion // Methods - Public
#region Protected
/// <summary>
/// Gets called when the rendering size of this control changes.
/// </summary>
/// <param name="sizeInfo">Information on the size change.</param>
protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo)
{
Console.WriteLine("{0}x{1}", sizeInfo.NewSize.Width, sizeInfo.NewSize.Height);
_widthDifference += sizeInfo.NewSize.Width - sizeInfo.PreviousSize.Width;
_heightDifference += sizeInfo.NewSize.Height - sizeInfo.PreviousSize.Height;
int columnDifference = 0;
int rowDifference = 0;
if (_widthDifference > TileSize || _widthDifference < TileSize*-1)
{
columnDifference = ((Int32) _widthDifference)/TileSize;
Columns += columnDifference;
_widthDifference = 0;
}
if (_heightDifference > TileSize || _heightDifference < TileSize*-1)
{
rowDifference = ((Int32) _heightDifference)/TileSize;
Rows += rowDifference;
_heightDifference = 0;
}
UpdateTileSet(columnDifference, rowDifference);
}
#endregion // Methods - Protected
#region Private
/// <summary>
/// Updates the number of tiles if the control changed in size.
/// </summary>
private void UpdateTileSet(Int32 columnChange, Int32 rowChange)
{
// Exit if there's no practical change
if (columnChange == 0 && rowChange == 0)
{
return;
}
// Delete all tiles that fall out on vertical resize
if (rowChange < 0)
{
for (var row = Rows; row > Rows + rowChange; row--)
{
for (var column = 0; column < Columns; column++)
{
Children.RemoveRange(GetListIndex(0, Rows), Columns);
}
}
}
// Delete all tiles that fall out on horizontal resize
if (columnChange < 0)
{
for (var column = Columns; column > Columns + columnChange; column--)
{
for (var row = 0; row < Rows; row++)
{
Children.RemoveAt(GetListIndex(column, row));
}
}
}
// Fill new rows with tiles on vertical resize
if (rowChange > 0)
{
for (var row = Rows - rowChange; row < Rows; row++)
{
for (var column = 0; column < Columns; column++)
{
var tile = new Tile(column, row);
Point position = GetCanvasPosition(column, row);
var index = GetListIndex(column, row);
SetLeft(tile, position.X);
SetTop(tile, position.Y);
Children.Insert(index, tile);
}
}
}
// The first population is a special case that can be handled
// by filling rows only.
if (_firstCreation)
{
_firstCreation = false;
return;
}
// Fill new columns with tiles on horizontal resize
if (columnChange > 0)
{
for (var column = Columns - columnChange; column < Columns; column++)
{
for (var row = 0; row < Rows; row++)
{
var tile = new Tile(column, row);
Point position = GetCanvasPosition(column, row);
var index = GetListIndex(column, row);
SetLeft(tile, position.X);
SetTop(tile, position.Y);
Children.Insert(index, tile);
}
}
}
}
/// <summary>
/// Returns the index a tile should occupy based on its column and row.
/// </summary>
/// <param name="column">The column in which this tile resides.</param>
/// <param name="row">The row in which this tile resides.</param>
/// <returns></returns>
private Int32 GetListIndex(Int32 column, Int32 row)
{
return row*Columns + column;
}
/// <summary>
/// Returns the coordinates of a specific position.
/// </summary>
/// <param name="column">The column the position is in.</param>
/// <param name="row">The row the position is in.</param>
/// <returns></returns>
private Point GetCanvasPosition(Int32 column, Int32 row)
{
var positionX = column*TileSize;
var positionY = row*TileSize;
return new Point(positionX, positionY);
}
#endregion // Methods - Private
#endregion // Methods
}
}
使用系统;
使用System.Windows;
使用System.Windows.Controls;
命名空间WpfApplication1.View
{
公共类TileCanvas:画布
{
#区域字段
私有布尔_firstCreation;
私人双高差;
私人双差;
#endregion//字段
#区域属性
公共静态只读从属属性TileSizeProperty=
从属属性寄存器(“TileSize”、typeof(Int32)、typeof(TileCanvas),
新的房地产数据(30));
公共Int32 TileSize
{
获取{return(Int32)GetValue(TileSizeProperty);}
set{SetValue(TileSizeProperty,value);}
}
公共Int32列{get;private set;}
公共Int32行{get;私有集;}
#endregion//属性
#区域构造函数
公共TileCanvas()
{
_第一次创造=真实;
}
#endregion//构造函数
#区域方法
#地区公众
#endregion//Methods-Public
#区域保护
///
///当此控件的呈现大小更改时调用。
///
///有关大小更改的信息。
受保护的覆盖无效OnRenderSizeChanged(SizeChangedInfo sizeInfo)
{
WriteLine(“{0}x{1}”,sizeInfo.NewSize.Width,sizeInfo.NewSize.Height);
_widthDifference+=sizeInfo.NewSize.Width-sizeInfo.PreviousSize.Width;
_heightDifference+=sizeInfo.NewSize.Height-sizeInfo.PreviousSize.Height;
积分差=0;
积分差=0;
如果(_widthDifference>TileSize | |_widthDifference波浪大小| | |高度差<波浪大小*-1)
{
行差=((Int32)_高度差)/TileSize;
行+=行差;
_高度差=0;
}
UpdateTileSet(列差异、行差异);
}
#endregion//方法-受保护
#地区私人
///
///如果控件的大小更改,则更新平铺的数量。
///
私有void更新集(Int32 columnChange、Int32 rowChange)
{
//如果没有实际变化,请退出
if(columnChange==0&&rowChange==0)
{
返回;
}
//删除垂直调整时掉出的所有平铺
如果(行更改<0)
{
对于(变量行=行;行>行+行更改;行--)
{
对于(变量列=0;列<列;列++)
{
RemoveRange(GetListIndex(0,行),列);
}
}
}
//删除水平方向上掉出的所有平铺调整大小
如果(列更改<0)
{
对于(变量列=列;列>列+列更改;列--)
{
对于(变量行=0;行<行;行++)
{
RemoveAt(GetListIndex(列,行));
}
}
}
//在垂直方向上用平铺填充新行
如果(行更改>0)
{
对于(变量行=行-行更改;行<行;行++)
{
对于(变量列=0;列<列;列++)
{
var瓷砖=新瓷砖(列、行);
点位置=GetCanvasPosition(列、行);
var index=GetListIndex(列、行);
SetLeft(瓷砖,位置X);
SetTop(瓷砖,位置Y);
插入(索引,平铺);
}
}
}
//第一批人是可以处理的特殊情况
//只填写行。
如果(_firstCreation)
{
_第一次创造=错误;
返回;
}
//在水平方向上用平铺填充新列
如果(列更改>0)
{
for(var column=Columns-columnChange;columnusing System;
using System.Windows.Controls;
namespace WpfApplication1.View
{
/// <summary>
/// Interaction logic for Tile.xaml
/// </summary>
public partial class Tile : Border
{
public Tile(Int32 column, Int32 row)
{
InitializeComponent();
Textfield.Text = String.Format("{0}x{1}", column, row);
}
}
}
<Border x:Class="WpfApplication1.View.Tile"
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"
Width="40" Height="40">
<TextBlock x:Name="Textfield" FontSize="8" HorizontalAlignment="Center" VerticalAlignment="Top"/>
</Border>