C# 如何在window store应用程序中限制画布内图像的转换

C# 如何在window store应用程序中限制画布内图像的转换,c#,windows-store-apps,winrt-xaml,transform,C#,Windows Store Apps,Winrt Xaml,Transform,我为这个问题挣扎了两周。我正在对画布内的图像应用拖动和缩放。拖动效果很好,并且限制了画布内的IsBoundary函数,但当我应用缩放时,其拖动区域会发生变化。如果用鼠标增加缩放比例,则拖动区域也会增加,当我使其缩小时,拖动区域也会缩小。请帮助我解决限制缩放的问题 谢谢 这是我的代码链接 我想我理解你的问题。在画布中缩放项目时,平移需要考虑缩放的变化。是这样吗 假设这个XAML: <Grid Background="{ThemeResource ApplicationPageBackgrou

我为这个问题挣扎了两周。我正在对画布内的图像应用拖动和缩放。拖动效果很好,并且限制了画布内的IsBoundary函数,但当我应用缩放时,其拖动区域会发生变化。如果用鼠标增加缩放比例,则拖动区域也会增加,当我使其缩小时,拖动区域也会缩小。请帮助我解决限制缩放的问题 谢谢 这是我的代码链接
我想我理解你的问题。在画布中缩放项目时,平移需要考虑缩放的变化。是这样吗

假设这个XAML:

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <Border Width="500"
            Height="500"
            BorderBrush="White"
            BorderThickness="1">
        <Canvas x:Name="MyCanvas">
            <Rectangle x:Name="MyRectangle"
                       Width="50"
                       Height="50"
                       Fill="CornflowerBlue">
                <Rectangle.RenderTransform>
                    <CompositeTransform TranslateX="225" TranslateY="225" />
                </Rectangle.RenderTransform>
            </Rectangle>
        </Canvas>
    </Border>
</Grid>

请尝试以下代码:

void MainPage_Loaded(object sender, RoutedEventArgs args)
{
    MyRectangle.ManipulationMode =
        ManipulationModes.TranslateX
        | ManipulationModes.TranslateY;
    var transform = MyRectangle.RenderTransform as CompositeTransform;
    var reposition = new Action<double, double>((x, y) =>
    {
        var size = new Size(MyRectangle.ActualWidth * transform.ScaleX, MyRectangle.ActualHeight * transform.ScaleY);
        var location = MyRectangle.TransformToVisual(MyRectangle).TransformPoint(new Point(0, 0));

        var minX = -location.X;
        var maxX = MyCanvas.ActualWidth - size.Width;
        var newX = Within(x, minX, maxX);
        transform.TranslateX = Within(newX, minX, maxX);

        var minY = -location.Y;
        var maxY = MyCanvas.ActualHeight - size.Height;
        var newY = Within(y, minY, maxX);
        transform.TranslateY = Within(newY, minY, maxY);
    });
    MyRectangle.ManipulationDelta += (s, e) =>
    {
        var newX = transform.TranslateX + e.Delta.Translation.X;
        var newY = transform.TranslateY + e.Delta.Translation.Y;
        reposition(newX, newY);
    };
    MyRectangle.PointerWheelChanged += (s, e) =>
    {
        // require control
        if (Window.Current.CoreWindow.GetKeyState(VirtualKey.Control)
            == Windows.UI.Core.CoreVirtualKeyStates.None)
            return;

        // ignore horizontal
        var props = e.GetCurrentPoint(MyRectangle).Properties;
        if (props.IsHorizontalMouseWheel)
            return;

        // apply scale
        var newScale = transform.ScaleX + (double)props.MouseWheelDelta * .001;
        transform.ScaleX = transform.ScaleY = newScale;

        // reposition
        reposition(transform.TranslateX, transform.TranslateY);
    };
}

public double Within(double value, double min, double max)
{
    if (value <= min)
        return min;
    else if (value >= max)
        return max;
    else
        return value;
}
void主页\u已加载(对象发送方、RoutedEventArgs参数)
{
MyRectangle.ManipulationMode=
操纵模式.TranslateX
|操纵模式。TranslateY;
var transform=MyRectangle.RenderTransform作为复合转换;
变量重新定位=新操作((x,y)=>
{
变量大小=新大小(MyRectangle.ActualWidth*transform.ScaleX、MyRectangle.ActualHeight*transform.ScaleY);
var location=MyRectangle.TransformToVisual(MyRectangle.TransformPoint)(新点(0,0));
var minX=-location.X;
var maxX=MyCanvas.ActualWidth-size.Width;
var newX=在(x,minX,maxX)范围内;
transform.TranslateX=内部(newX、minX、maxX);
var minY=-location.Y;
var maxY=MyCanvas.ActualHeight—size.Height;
var newY=在(y,minY,maxX)范围内;
transform.TranslateY=in(newY、minY、maxY);
});
MyRectangle.ManipulationDelta+=(s,e)=>
{
var newX=transform.TranslateX+e.Delta.Translation.X;
var newY=transform.TranslateY+e.Delta.Translation.Y;
重新定位(newX,newY);
};
MyRectangle.PointerHeelChanged+=(s,e)=>
{
//需要控制
if(Window.Current.CoreWindow.GetKeyState(VirtualKey.Control)
==Windows.UI.Core.CoreVirtualKeyState.None)
返回;
//忽略水平
var props=e.GetCurrentPoint(MyRectangle).Properties;
if(道具IsHorizontalMouseWheel)
返回;
//应用刻度
var newScale=transform.ScaleX+(双)props.mouseweelldelta*.001;
transform.ScaleX=transform.ScaleY=newScale;
//重新定位
重新定位(transform.TranslateX、transform.TranslateY);
};
}
公共双内(双值、双最小值、双最大值)
{
如果(值=最大值)
返回最大值;
其他的
返回值;
}
我希望这有帮助

注意:因为我现在不在触摸机上,所以我实现了鼠标滚轮的缩放。但是您可以根据需要修改代码。逻辑是相同的


祝你好运

这是预期的行为,您是说希望提供hittestvisibility的区域保持相同大小,而不管其当前比例如何?是的,画布保持不变,但缩放仅适用于图像,因此画布是缩放的,而不是图像?抱歉,有点困惑。首先拖动图像,效果很好。然后,当您点击图像时,其不透明度变为0.5,然后拖动将缩放的图像,然后再次点击使不透明度变为1。然后让它拖动你会在它的区域有一些不同。我希望当图像离开画布时,弹出一条消息显示,并说限制超出了不能再缩放的范围。很棒的工作兄弟你救了我(y)请解释一下?当然。resposition()是关键方法。它确保翻译不在
画布
的范围之外。只要确保在scale.if(MyRectangle.Opacity==0.5){var translate=(CompositeTransform)之后调用它进行转换MyRectangle.RenderTransform;translate.ScaleX+=e.Delta.Translation.X*0.005;//translate.ScaleY+=e.Delta.Translation.Y*0.005;//重新定位(transform.TranslateX,transform.TranslateY);}但是当我扩展更多的时候,它仍然在运行?为什么不用你的代码更新我的代码,这样我就可以看到它的完整性。或者你可以给我发电子邮件一个工作样本项目jnixon@microsoft(.com)