【问题标题】:UWP: Adjusting InkCanvas size when writing/drawingUWP:在书写/绘图时调整 InkCanvas 大小
【发布时间】:2021-02-02 16:18:49
【问题描述】:

我正在学习如何开发 UWP 应用,并且我正在使用 Microsoft 的文档作为教程/研究。

我想要一个类似于 OneNote 的 InkCanvas 设计,其中 InkCanvas 的高度和宽度可以扩展(当您正在书写/绘图并达到窗口大小的末端)并且可以缩小(当您擦除墨迹笔划和额外的大小可以根据墨水笔划的位置减小,直到恢复到原始大小)。

我可以增加 InkCanvas 的宽度和高度,但在擦除墨迹时不能减小。

这是一个 MainPage.xaml 代码:

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>

    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>

    <TextBlock Text="Heading"
                   FontSize="36"
                   FontWeight="Bold"
                   Margin="10"
                   Grid.Column="0"
                   Grid.Row="0"/>

    <Grid BorderBrush="Red"
                    BorderThickness="2"
                    Margin="10"
                    Grid.Column="0"
                    Grid.Row="1">
        <ScrollViewer HorizontalScrollBarVisibility="Auto"
                      HorizontalScrollMode="Enabled"
                      VerticalScrollBarVisibility="Auto"
                      VerticalScrollMode="Enabled" >

            <Grid BorderBrush="Blue"
                    BorderThickness="2"
                    Margin="1">
                <InkCanvas Name="inkCanvas"/>
            </Grid>
        </ScrollViewer>

    </Grid>

还有 MainPage.cs 代码:

public MainPage()
    {
        this.InitializeComponent();
        nkCanvas.InkPresenter.StrokeInput.StrokeEnded += adjustInkCanvasSize;
    }

    private  async void adjustInkCanvasSize(InkStrokeInput sender, PointerEventArgs args)
    {
        await Task.Delay(100);

        var XBound = inkCanvas.InkPresenter.StrokeContainer.BoundingRect.Bottom;
        if (XBound > inkCanvas.ActualHeight - 200)
            inkCanvas.Height = XBound + 200;

        var YBound = inkCanvas.InkPresenter.StrokeContainer.BoundingRect.Right;
        if (YBound > inkCanvas.ActualWidth - 200)
            inkCanvas.Width = YBound + 200;
     }

c# 代码也来自另一个 stackoverflow 解决方案,但无法弄清楚“减少”部分。

任何帮助将不胜感激。谢谢

【问题讨论】:

    标签: c# xaml uwp


    【解决方案1】:

    如果您希望InkCanvas控件在您擦除墨迹时缩小,并且额外的大小可以根据墨迹的位置减小直到原始大小,您需要添加InkPresenter.StrokesErased事件来管理大小InkCanvas 控件的。例如:

    这是一个MainPage.xaml的代码(为了方便测试,我添加了鼠标支持):

    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
    
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
    
        <TextBlock Text="Heading"
                   FontSize="36"
                   FontWeight="Bold"
                   Margin="10"
                   Grid.Column="0"
                   Grid.Row="0"/>
    
        <Grid BorderBrush="Red"
                    BorderThickness="2"
                    Margin="10"
                    Grid.Column="0"
                    Grid.Row="1">
            <Grid.RowDefinitions>
                <RowDefinition Height="auto"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
    
            <InkToolbar x:Name="inkToolbar" VerticalAlignment="Top" Margin="10,0,10,0"
                                TargetInkCanvas="{x:Bind inkCanvas}" Grid.Row="0"/>
            <ScrollViewer HorizontalScrollBarVisibility="Auto"
                      HorizontalScrollMode="Enabled" Grid.Row="1"
                      VerticalScrollBarVisibility="Auto"
                      VerticalScrollMode="Enabled" >
    
                <Grid BorderBrush="Blue"
                    BorderThickness="2"
                    Margin="1">
                    
                    <InkCanvas Name="inkCanvas" />
                    
                </Grid>
            </ScrollViewer>
    
        </Grid>
    </Grid>
    

    还有MainPage.cs 代码:

    public sealed partial class MainPage : Page
    {
        private double originalX; //The original size
        private double originalY;
        private double maxX=0.0; 
        private double maxY=0.0;
        private bool flag = true;
        public MainPage()
        {
            this.InitializeComponent();
    
            inkCanvas.InkPresenter.InputDeviceTypes = CoreInputDeviceTypes.Mouse | CoreInputDeviceTypes.Touch |
                CoreInputDeviceTypes.Pen;
            inkCanvas.InkPresenter.StrokeInput.StrokeEnded += adjustInkCanvasSize;
            inkCanvas.InkPresenter.StrokesErased += InkPresenter_StrokesErased;
        }
    
        private async void InkPresenter_StrokesErased(InkPresenter sender, InkStrokesErasedEventArgs args)
        {
            await Task.Delay(100);
    
            //The coordinate of the lower right corner of the erased ink stoke
            var erasedInkX= args.Strokes.ElementAt(0).BoundingRect.Bottom;
            var erasedInkY = args.Strokes.ElementAt(0).BoundingRect.Right;
            
            var XBound = inkCanvas.InkPresenter.StrokeContainer.BoundingRect.Bottom;
            if (erasedInkX >=maxX&&XBound < inkCanvas.ActualHeight + 100)
            {
                if (XBound - 100 > originalX)
                    inkCanvas.Height = XBound - 100;
                else
                    inkCanvas.Height = originalX;  //The size of InkCanvas shrinks to the original size.
    
                maxX = inkCanvas.Height;
            }
                
            var YBound = inkCanvas.InkPresenter.StrokeContainer.BoundingRect.Right;
            if (erasedInkY>=maxY&&YBound < inkCanvas.ActualWidth + 100)
            {
                if (YBound - 100 > originalY)
                {
                    inkCanvas.Width = YBound - 100;
                }
                else
                    inkCanvas.Width = originalY;
    
                maxY = inkCanvas.Width;
            }
        }
    
        private async void adjustInkCanvasSize(InkStrokeInput sender, PointerEventArgs args)
        {
            await Task.Delay(100);
    
            if(flag)
            {
                flag = false;
                originalX = inkCanvas.ActualHeight;  //Get the original size 
                originalY = inkCanvas.ActualWidth;
            }
            var XBound = inkCanvas.InkPresenter.StrokeContainer.BoundingRect.Bottom;
            if (XBound > maxX)
                maxX = XBound;  //maxX and maxY always hold the maximum size of StrokeContainer
    
            if (XBound > inkCanvas.ActualHeight - 200)
                inkCanvas.Height = XBound + 200;
    
            var YBound = inkCanvas.InkPresenter.StrokeContainer.BoundingRect.Right;
            if (YBound > maxY)
                maxY = YBound;
    
            if (YBound > inkCanvas.ActualWidth - 200)
                inkCanvas.Width = YBound + 200;
        }
    }
    

    【讨论】:

    • 非常感谢!在看到您的解决方案并在减小InkCanvas 大小方面取得了一些进展之前,我实际上正在查找如何在代码中使用InkPresenter.StrokesErased,但仍然无法正常工作。一旦我看到您的解决方案并将其添加到我的代码中,它就会完美运行!感谢您的帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-12-01
    • 1970-01-01
    • 2019-01-07
    • 2016-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多