تمام سوالات سوالات بدون پاسخ سوال بپرسید

میخوام برنامه ای برای نمایش تصاویر در WPF ایجاد کنم که کاربر را قادر سازد تا:
عمل pan را با دراگ کردن تصویر توسط ماوس انجام دهد.
عمل zoom را با slider انجام دهد.
همپوشانی ها را نمایش دهد.(به عنوان مثال انتخاب یک کادر مستطیل شکل)
تصویر اولیه را نمایش دهد(در صورت نیاز توسط یک اسکرول بار).
آیا می توانید چگونگی انجام این کار را توضیح دهید؟
من نتوانستم مثال خوبی را برای این کار در اینترنت پیدا کنم. آیا باید از ViewBox استفاده کنم؟ و یا از imageBrush؟آیا نیازی به ScrollViewer دارم؟
ممنون

منبع:
stackoverflow

2 پاسخ

راهی که برای حل این مشکل وجود دارد قرار دادن تصویر در داخل یک Border با true کردن ویژگی ClipToBounds مربوطه می باشد. پس از آن ویژگی RenderTransformOrigin مربوطه به آن برابر 0.5،0.5 ست می شود تا تصویر شروع بزرگنمایی از نقطه مرکزی نماید. ویژگی RenderTransform نیز به یک TransformGroup شامل ScaleTransform و TranslateTransform ست می شود.
اکنون من رویداد MouseWheel مربوط به تصویر را برای عمل Zoom ایجاد می کنم:

private void image_MouseWheel(object sender, MouseWheelEventArgs e)
{
    var st = (ScaleTransform)image.RenderTransform;
    double zoom = e.Delta > 0 ? .2 : -.2;
    st.ScaleX += zoom;
    st.ScaleY += zoom;
}

برای فراهم ساختن امکان pan در تصویر نخست باید رویداد MouseLeftButtonDown بمنظور ذخیره موقعیت ماوس نوشته شود. من همچنین مقدار فعلی TranslateTransform را ذخیره می نمایم.این همان چیزی است که برای پیاده سازی pan بروز می شود.

Point start;
Point origin;
private void image_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    image.CaptureMouse();
    var tt = (TranslateTransform)((TransformGroup)image.RenderTransform)
        .Children.First(tr => tr is TranslateTransform);
    start = e.GetPosition(border);
    origin = new Point(tt.X, tt.Y);
}

پس از آن من رویداد MouseMove را برای بروز رسانی TranslateTransform بکار می گیرم.

private void image_MouseMove(object sender, MouseEventArgs e)
{
    if (image.IsMouseCaptured)
    {
        var tt = (TranslateTransform)((TransformGroup)image.RenderTransform)
            .Children.First(tr => tr is TranslateTransform);
        Vector v = start - e.GetPosition(border);
        tt.X = origin.X - v.X;
        tt.Y = origin.Y - v.Y;
    }
}

در انتها فراموش نکنید که تابع ReleaseMouseCapture() را اجرا نمایید

private void image_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
    image.ReleaseMouseCapture();
}

فراخوانی CaptureMouse در image_MouseLeftButtonDown باعث اجرای image_MouseMove می گردد که مبدا آن هنوز ایجاد نگشته است – در کد بالا این مقدار صفر خواهد شد اما چنانچه مبدا آن مقداری غیر از (0,0) بگیرد، پرش کوچکی در تصویر ایجاد خواهد شد. از این رو بهتر است image.CaptureMouse() را در انتهای image_MouseLeftButtonDown فراخوانی کنیم.

(30 اوت '11, 05:31) hamedkh ♦

دو مساله وجود دارد: 1. در هنگام استفاده از image_MouseWheel یک باگ (bug) وجود دارد. شما باید ScaleTransform را به روش مشابه با TranslateTransform بگیرید. این مسئله منجر می شود که عمل تغییر نوع (cast) به یک TransformGroup انجام گیرد و در نتیجه فرزند (child) مربوطه به آن نیز انتخاب و عمل cast برای آن نیز صورت پذیرد. 2. توجه کنید که اگر حرکت شما سریع و شدید باشد نمی توانید از تصویر برای تعیین موقعیت ماوس استفاده کنید(بخاطر داینامیک بودن آن). برای این کار حتما باید از اشیاء استاتیک استفاده شود.در این مثال از یک Border استفاده می شود.

(30 اوت '11, 05:31) hamedkh ♦

پاسخی که در بالا ارائه شده است پاسخ کاملی نمی باشد. جواب کاملتر در زیر آمده است:
XAML

<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="MapTest.Window1"
x:Name="Window"
Title="Window1"
Width="1950" Height="1546" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:Controls="clr-namespace:WPFExtensions.Controls;assembly=WPFExtensions" mc:Ignorable="d" Background="#FF000000">

<Grid x:Name="LayoutRoot">
    <Grid.RowDefinitions>
        <RowDefinition Height="52.92"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>

    <Border Grid.Row="1" Name="border">
        <Image Name="image" Source="map3-2.png" Opacity="1" RenderTransformOrigin="0.5,0.5"  />
    </Border>

</Grid>
</Window>

Code Behind

using System.Linq;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;

namespace MapTest
{
    public partial class Window1 : Window
    {
        private Point origin;
        private Point start;

        public Window1()
        {
            InitializeComponent();

            TransformGroup group = new TransformGroup();

            ScaleTransform xform = new ScaleTransform();
            group.Children.Add(xform);

            TranslateTransform tt = new TranslateTransform();
            group.Children.Add(tt);

            image.RenderTransform = group;

            image.MouseWheel += image_MouseWheel;
            image.MouseLeftButtonDown += image_MouseLeftButtonDown;
            image.MouseLeftButtonUp += image_MouseLeftButtonUp;
            image.MouseMove += image_MouseMove;
        }

        private void image_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            image.ReleaseMouseCapture();
        }

        private void image_MouseMove(object sender, MouseEventArgs e)
        {
            if (!image.IsMouseCaptured) return;

            var tt = (TranslateTransform) ((TransformGroup) image.RenderTransform).Children.First(tr => tr is TranslateTransform);
            Vector v = start - e.GetPosition(border);
            tt.X = origin.X - v.X;
            tt.Y = origin.Y - v.Y;
        }

        private void image_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            image.CaptureMouse();
            var tt = (TranslateTransform) ((TransformGroup) image.RenderTransform).Children.First(tr => tr is TranslateTransform);
            start = e.GetPosition(border);
            origin = new Point(tt.X, tt.Y);
        }

        private void image_MouseWheel(object sender, MouseWheelEventArgs e)
        {
            TransformGroup transformGroup = (TransformGroup) image.RenderTransform;
            ScaleTransform transform = (ScaleTransform) transformGroup.Children[0];

            double zoom = e.Delta > 0 ? .2 : -.2;
            transform.ScaleX += zoom;
            transform.ScaleY += zoom;
        }
    }
}

من در وب سایت خود مثال کاملی از یک برنامه WPF دارم که در آن از این کد استفاده شده است:
http://jarloo.com/code/projects/jot

آیا پیشنهادی راجع به نحوه استفاده این کد در silverlight 3 دارید؟ من در زمینه Vector ها و کم کردن یک نقطه از نقطه ای دیگر مشکل دارم.

(30 اوت '11, 05:34) hamedkh ♦

برنامه بسیار خوبی است . بسیار خوب کار می کند.

(30 اوت '11, 05:34) hamedkh ♦
toggle preview



آموزش زبان برنامه نویسی C#
آموزش jquery
آموزش برنامه نویسی
آموزش طراحی وبسایت
آموزش مدیریت وبسایت
آموزش جاوا Java
آموزش پایتون Python
آموزش سی شارپ C#‎
آموزش HTML و CSS
آموزش JavaScript جاوااسکریپت
آموزش jQuery جی کوئری
آموزش ساخت ربات تلگرام
آموزش برنامه‌نویسی PHP
آموزش برنامه‌نویسی اندروید
● آموزش‌های رایگان

سوالات مرتبط

راهنمای استفاده از ویرایشگر
  • *ایتالیک*‌ یا __ایتالیک__
  • **ضخیم** یا __ضخیم__
  • آدرس:[متن](http://url.com/ "عنوان")
  • عکس?![alt متن](/path/img.jpg "عنوان")
  • لیست عددی: 1. Foo 2. Bar
  • برای رفتن به خط بعد، هر جا مایلید که خط جدید شروع شود دو کاراکتر فاصله (space) قرار دهید
  • تگ‌های ساده HTML هم پشتیبانی می‌شوند

تگها:
  • ×209
  • ×137
  • ×54
  • ×40
  • پرسیده شده: 30 اوت '11, 05:26
  • بازدید: 3,366 بار
  • آخرین بروزرسانی: 11 سپتامبر '11, 06:45

این سوال را دنبال کنیدتوسط ایمیل: ایمیل شما (باید معتبر باشد, هرگز به دیگران نمایش داده نمیشود):

هنگامی که شما به سیستم وارد شوید،قادر خواهید بود برای بروز رسانی ها مشترک شوید.


توسط RSS:

پاسخها

پاسخها و نظرها