Joe*_*ite 3 wpf dependency-properties
当我尝试在运行时更改CroppedBitmap的SourceRect属性时,没有任何反应.没有错误,属性值实际上没有改变.
我正在尝试做精灵动画.我有一个包含spritesheet的BitmapSource,它是一个包含精灵不同姿势网格的单个位图.然后我有一个CroppedBitmap,它有spritesheet作为Source,还有一个SourceRect,它从spritesheet中拉出一个姿势.在运行时,当我想要设置动画时,我正在尝试更改CroppedBitmap的SourceRect属性,以从较大的位图中拉出不同的姿势; 但是,如上所述,新的财产价值根本不坚持.这是最奇怪的事情.
这是一些示例XAML:
<UserControl.Resources>
<BitmapImage x:Key="spritesheet" UriSource="Sprites/elf.png"/>
</UserControl.Resources>
<Image>
<Image.Source>
<CroppedBitmap x:Name="image" Source="{StaticResource spritesheet}"
SourceRect="240 640 240 320"/>
</Image.Source>
</Image>
Run Code Online (Sandbox Code Playgroud)
代码隐藏试图这样做:
var newRect = new Int32Rect(...);
Debug.WriteLine(" Before: " + image.SourceRect);
Debug.WriteLine("Assigning new value: " + newRect);
image.SourceRect = newRect;
Debug.WriteLine(" After: " + image.SourceRect);
Run Code Online (Sandbox Code Playgroud)
这给了我这个调试输出:
Before: 240,640,240,320
Assigning new value: 240,0,240,320
After: 240,640,240,320
Run Code Online (Sandbox Code Playgroud)
所以它实际上是将新的矩形(Y = 0)分配给属性; 没有例外; 但之后,财产价值根本没有改变(Y仍然是640).
关于为什么会发生这种情况的任何想法,以及如何解决它?
Joe*_*ite 15
我终于找到了答案.从CroppedBitmap的文档:
CroppedBitmap实现ISupportInitialize接口以优化多个属性的初始化.只有在对象初始化期间才会发生属性更改 调用BeginInit表示初始化已经开始,EndInit表示初始化已完成.初始化后,将忽略属性更改. (强调我的)
只是为了好玩,我尝试在我的方法中添加BeginInit().. EndInit()调用,以查看是否可以使其可修改.毫不奇怪,我得到了一个InvalidOperationException("不能多次设置初始化状态").
所以CroppedBitmap实际上是不可变的.(但是他们忽略了他们自己的Freezable系统,这个系统会抛出一个异常来告诉我我做错了什么,并实现了更令人惊讶的东西.)
这意味着,不要改变SourceRect属性.我需要为spritesheet中的每个子图像创建一个单独的CroppedBitmap实例.
以下是另一种处理此问题的方法:使用完整的源图像,而
不是使用a CroppedBitmap,但是:
image.RenderTransform以调整可视区域.Image.Clip如有必要,请设置,以避免显示图像中不需要的部分.这意味着您不需要继续制作新的CroppedBitmaps,您只需调整变换即可.
在我的测试中,我发现速度无论如何都没有区别.
为了完整起见,这是我如何调整代码以执行我的建议:
<Image RenderTransform="1, 0, 0, 1, -240, -640">
<!-- Still include your Image.Source here, just not as a CroppedBitmap -->
<Image.Clip>
<RectangleGeometry Rect="0, 0, 240, 320" />
</Image.Clip>
</Image>
Run Code Online (Sandbox Code Playgroud)
然后后来调用相当于调整SourceRect是:
image.RenderTransform = new MatrixTransform(1d, 0d, 0d, 1d, -240d, 0d);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3234 次 |
| 最近记录: |