Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Wpf OnRenderSizeChanged是否未正确调用?_Wpf - Fatal编程技术网

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>