You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Avalonia UI中Thumb控件不显示的问题排查求助

Avalonia Thumb控件不显示的原因及解决示例

问题原因

Avalonia的Thumb控件默认没有内置可视化模板,直接设置Background、Width等属性不会生效——因为没有模板来渲染这些视觉元素,所以你只能看到绿色的Canvas,Thumb本身完全没被渲染出来。

解决方法:给Thumb添加ControlTemplate

必须为每个Thumb定义ControlTemplate,让它显示出可视化外观。下面是修改后的完整代码,同时附带了基础的拖动调整Canvas大小的逻辑:

修改后的XAML代码

<UserControl xmlns="https://github.com/avaloniaui"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             x:Class="YourNamespace.YourUserControl">
    <Canvas x:Name="resizeCanvas" Width="200" Height="200" Background="Lime">
        <!-- Corner Resize Handles -->
        <Thumb Name="TopLeftThumb" Cursor="TopLeftCorner">
            <Thumb.Style>
                <Style TargetType="Thumb">
                    <Setter Property="Template">
                        <ControlTemplate>
                            <Border Background="Red" Width="10" Height="10"/>
                        </ControlTemplate>
                    </Setter>
                </Style>
            </Thumb.Style>
        </Thumb>
        <Thumb Name="TopRightThumb" Cursor="TopRightCorner">
            <Thumb.Style>
                <Style TargetType="Thumb">
                    <Setter Property="Template">
                        <ControlTemplate>
                            <Border Background="Red" Width="10" Height="10"/>
                        </ControlTemplate>
                    </Setter>
                </Style>
            </Thumb.Style>
        </Thumb>
        <Thumb Name="BottomLeftThumb" Cursor="BottomLeftCorner">
            <Thumb.Style>
                <Style TargetType="Thumb">
                    <Setter Property="Template">
                        <ControlTemplate>
                            <Border Background="Red" Width="10" Height="10"/>
                        </ControlTemplate>
                    </Setter>
                </Style>
            </Thumb.Style>
        </Thumb>
        <Thumb Name="BottomRightThumb" Cursor="BottomRightCorner">
            <Thumb.Style>
                <Style TargetType="Thumb">
                    <Setter Property="Template">
                        <ControlTemplate>
                            <Border Background="Red" Width="10" Height="10"/>
                        </ControlTemplate>
                    </Setter>
                </Style>
            </Thumb.Style>
        </Thumb>

        <!-- Edge Resize Handles -->
        <Thumb Name="TopThumb" Cursor="TopSide">
            <Thumb.Style>
                <Style TargetType="Thumb">
                    <Setter Property="Template">
                        <ControlTemplate>
                            <Border Background="Red" Height="10" Width="180"/>
                        </ControlTemplate>
                    </Setter>
                </Style>
            </Thumb.Style>
        </Thumb>
        <Thumb Name="BottomThumb" Cursor="BottomSide">
            <Thumb.Style>
                <Style TargetType="Thumb">
                    <Setter Property="Template">
                        <ControlTemplate>
                            <Border Background="Red" Height="10" Width="180"/>
                        </ControlTemplate>
                    </Setter>
                </Style>
            </Thumb.Style>
        </Thumb>
        <Thumb Name="LeftThumb" Cursor="LeftSide">
            <Thumb.Style>
                <Style TargetType="Thumb">
                    <Setter Property="Template">
                        <ControlTemplate>
                            <Border Background="Red" Width="10" Height="180"/>
                        </ControlTemplate>
                    </Setter>
                </Style>
            </Thumb.Style>
        </Thumb>
        <Thumb Name="RightThumb" Cursor="RightSide">
            <Thumb.Style>
                <Style TargetType="Thumb">
                    <Setter Property="Template">
                        <ControlTemplate>
                            <Border Background="Red" Width="10" Height="180"/>
                        </ControlTemplate>
                    </Setter>
                </Style>
            </Thumb.Style>
        </Thumb>
    </Canvas>
</UserControl>

后端C#拖动逻辑示例

在UserControl的代码后台添加DragDelta事件处理,实现Canvas大小调整:

using Avalonia;
using Avalonia.Controls;
using Avalonia.Input;

namespace YourNamespace;

public partial class YourUserControl : UserControl
{
    public YourUserControl()
    {
        InitializeComponent();
        AttachDragHandlers();
    }

    private void AttachDragHandlers()
    {
        BottomRightThumb.DragDelta += BottomRightThumb_DragDelta;
        TopRightThumb.DragDelta += TopRightThumb_DragDelta;
        BottomLeftThumb.DragDelta += BottomLeftThumb_DragDelta;
        TopLeftThumb.DragDelta += TopLeftThumb_DragDelta;
        TopThumb.DragDelta += TopThumb_DragDelta;
        BottomThumb.DragDelta += BottomThumb_DragDelta;
        LeftThumb.DragDelta += LeftThumb_DragDelta;
        RightThumb.DragDelta += RightThumb_DragDelta;
    }

    private void BottomRightThumb_DragDelta(object? sender, VectorEventArgs e)
    {
        resizeCanvas.Width = Math.Max(10, resizeCanvas.Width + e.Vector.X);
        resizeCanvas.Height = Math.Max(10, resizeCanvas.Height + e.Vector.Y);
        UpdateThumbPositions();
    }

    private void TopRightThumb_DragDelta(object? sender, VectorEventArgs e)
    {
        resizeCanvas.Width = Math.Max(10, resizeCanvas.Width + e.Vector.X);
        var newHeight = resizeCanvas.Height - e.Vector.Y;
        if (newHeight >= 10)
        {
            resizeCanvas.Height = newHeight;
            Canvas.SetTop(resizeCanvas, Canvas.GetTop(resizeCanvas) + e.Vector.Y);
        }
        UpdateThumbPositions();
    }

    private void BottomLeftThumb_DragDelta(object? sender, VectorEventArgs e)
    {
        var newWidth = resizeCanvas.Width - e.Vector.X;
        if (newWidth >= 10)
        {
            resizeCanvas.Width = newWidth;
            Canvas.SetLeft(resizeCanvas, Canvas.GetLeft(resizeCanvas) + e.Vector.X);
        }
        resizeCanvas.Height = Math.Max(10, resizeCanvas.Height + e.Vector.Y);
        UpdateThumbPositions();
    }

    private void TopLeftThumb_DragDelta(object? sender, VectorEventArgs e)
    {
        var newWidth = resizeCanvas.Width - e.Vector.X;
        var newHeight = resizeCanvas.Height - e.Vector.Y;
        if (newWidth >= 10 && newHeight >= 10)
        {
            resizeCanvas.Width = newWidth;
            resizeCanvas.Height = newHeight;
            Canvas.SetLeft(resizeCanvas, Canvas.GetLeft(resizeCanvas) + e.Vector.X);
            Canvas.SetTop(resizeCanvas, Canvas.GetTop(resizeCanvas) + e.Vector.Y);
        }
        UpdateThumbPositions();
    }

    private void TopThumb_DragDelta(object? sender, VectorEventArgs e)
    {
        var newHeight = resizeCanvas.Height - e.Vector.Y;
        if (newHeight >= 10)
        {
            resizeCanvas.Height = newHeight;
            Canvas.SetTop(resizeCanvas, Canvas.GetTop(resizeCanvas) + e.Vector.Y);
        }
        UpdateThumbPositions();
    }

    private void BottomThumb_DragDelta(object? sender, VectorEventArgs e)
    {
        resizeCanvas.Height = Math.Max(10, resizeCanvas.Height + e.Vector.Y);
        UpdateThumbPositions();
    }

    private void LeftThumb_DragDelta(object? sender, VectorEventArgs e)
    {
        var newWidth = resizeCanvas.Width - e.Vector.X;
        if (newWidth >= 10)
        {
            resizeCanvas.Width = newWidth;
            Canvas.SetLeft(resizeCanvas, Canvas.GetLeft(resizeCanvas) + e.Vector.X);
        }
        UpdateThumbPositions();
    }

    private void RightThumb_DragDelta(object? sender, VectorEventArgs e)
    {
        resizeCanvas.Width = Math.Max(10, resizeCanvas.Width + e.Vector.X);
        UpdateThumbPositions();
    }

    private void UpdateThumbPositions()
    {
        // 更新角落Thumb位置
        Canvas.SetLeft(TopLeftThumb, Canvas.GetLeft(resizeCanvas));
        Canvas.SetTop(TopLeftThumb, Canvas.GetTop(resizeCanvas));

        Canvas.SetLeft(TopRightThumb, Canvas.GetLeft(resizeCanvas) + resizeCanvas.Width - 10);
        Canvas.SetTop(TopRightThumb, Canvas.GetTop(resizeCanvas));

        Canvas.SetLeft(BottomLeftThumb, Canvas.GetLeft(resizeCanvas));
        Canvas.SetTop(BottomLeftThumb, Canvas.GetTop(resizeCanvas) + resizeCanvas.Height - 10);

        Canvas.SetLeft(BottomRightThumb, Canvas.GetLeft(resizeCanvas) + resizeCanvas.Width - 10);
        Canvas.SetTop(BottomRightThumb, Canvas.GetTop(resizeCanvas) + resizeCanvas.Height - 10);

        // 更新边缘Thumb位置
        Canvas.SetLeft(TopThumb, Canvas.GetLeft(resizeCanvas) + 10);
        Canvas.SetTop(TopThumb, Canvas.GetTop(resizeCanvas));
        TopThumb.Width = resizeCanvas.Width - 20;

        Canvas.SetLeft(BottomThumb, Canvas.GetLeft(resizeCanvas) + 10);
        Canvas.SetTop(BottomThumb, Canvas.GetTop(resizeCanvas) + resizeCanvas.Height - 10);
        BottomThumb.Width = resizeCanvas.Width - 20;

        Canvas.SetLeft(LeftThumb, Canvas.GetLeft(resizeCanvas));
        Canvas.SetTop(LeftThumb, Canvas.GetTop(resizeCanvas) + 10);
        LeftThumb.Height = resizeCanvas.Height - 20;

        Canvas.SetLeft(RightThumb, Canvas.GetLeft(resizeCanvas) + resizeCanvas.Width - 10);
        Canvas.SetTop(RightThumb, Canvas.GetTop(resizeCanvas) + 10);
        RightThumb.Height = resizeCanvas.Height - 20;
    }
}

关键说明

  • Thumb的核心是处理拖动事件,可视化外观完全依赖你定义的ControlTemplate,可以用Border、Rectangle等元素自定义样式(比如改颜色、加圆角)。
  • 拖动逻辑通过DragDelta事件获取偏移量,调整Canvas尺寸和位置后,要同步更新所有Thumb的位置,保证它们始终贴合Canvas边缘。

内容的提问来源于stack exchange,提问作者Der_Floh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 05:15:57