如何建立一个大画布 [英] How to build a big Canvas

查看:71
本文介绍了如何建立一个大画布的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

亲爱的

我正在为客户提供一种特定的协作应用程序,该应用程序与数字董事会过去几年展示的功能非常相似,但简单得多.

I am buidling for a customer a specific collaborative application quite similar what digital board are showing those past year but much simpler.

事实上,我需要做的是以下事情:

In fact what I need to do is the following :

我需要制作一种至少是屏幕大小三倍的大画布,以便人们可以开始在屏幕上书写笔记,如果没有更多空间,他们可以将屏幕向右,向上或向下滑动

I need to build a kind of big canvas at least 3 time the size of the screen in order that people can start to write notes in screen and if there is no more room they can slide the screen to right, up or down.

但是,我需要在图片中添加一罐Picture来显示完整的画布区域和使用过的区域,如下所示:

But with that I need to add a can of Picture in picture to show the full canvas area and the used area as shown below :

从上方的图片可以看到,画布大于可见的屏幕区域.底部纬纱上的小窗口将完整的画布显示为带有对象位置的对象,以告知用户该对象所在的位置.然后用户知道,如果他对主要 屏幕右侧的区域,他将能够看到其他内容类型.

As you can see from picture above the canvas is bigger that the visible screen area. The small window on bottom letft is showing the full canvas with object position to informed user where conatent are located. Then user knows that if he scrool the main screen area to right he will be able to see the other content type.

如果将对象从主屏幕中移出,它也会反映在小窗口中.

If an object is moved from the main screen it is also reflected in the small window.

有什么想法如何在小窗口代表整个画布区域的情况下建立这种交互?

Any idea how to build such interaction where small windows represent the whole canvas area ?

感谢帮助

推荐答案

wakefun,

Hi wakefun,

在ViewBox中创建画布.

Create a Canvas in the ViewBox.

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:app="clr-namespace:WpfApplication1"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <app:SolidBrushConverter x:Key="brushConverter"/>
    </Window.Resources>
    <Grid>
        <ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto"
                      ScrollChanged="ScrollViewer_ScrollChanged">
            <ItemsControl ItemsSource="{Binding Path=Items}" BorderThickness="0" x:Name="full" VerticalAlignment="Top" HorizontalAlignment="Left"
                     Width="{Binding Path=CanvasWidth}" Height="{Binding Path=CanvasHeight}">
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <Canvas x:Name="fullCanvas"
                                Width="{Binding Path=ActualWidth,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type ItemsControl}}}" 
                                Height="{Binding Path=ActualHeight,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type ItemsControl}}}"
                                Background="LightBlue"/>
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>

                <ItemsControl.ItemContainerStyle>
                    <Style TargetType="ContentPresenter">
                        <Setter Property="Canvas.Left" Value="{Binding Path=X,Mode=TwoWay}" />
                        <Setter Property="Canvas.Top" Value="{Binding Path=Y,Mode=TwoWay}" />
                    </Style>
                </ItemsControl.ItemContainerStyle>

                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <Grid>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="Auto"/>
                                <ColumnDefinition />
                                <ColumnDefinition Width="Auto"/>
                            </Grid.ColumnDefinitions>
                            <Grid.RowDefinitions>
                                <RowDefinition />
                                <RowDefinition />
                            </Grid.RowDefinitions>


                            <Thumb x:Name="move"  DragDelta="moveThumb_DragDelta" 
                                   Tag="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type ContentPresenter}}}"
                                   Cursor="ScrollAll" Width="5" Background="Black"/>

                            <Border  Grid.Column="1" BorderThickness="0" x:Name="border"                               
                                Background="{Binding Path=Color,Converter={StaticResource brushConverter}}"
                                Width="{Binding Path=Width,Mode=TwoWay}"
                                Height="{Binding Path=Height,Mode=TwoWay}">
                                <TextBox Text="{Binding Path=Text}" Background="Transparent" BorderThickness="0"/>
                            </Border>

                            <Thumb x:Name="resize"  DragDelta="resizeThumb_DragDelta" Tag="{Binding ElementName=border}"
                                   Cursor="SizeNWSE" Width="5" Height="5" Background="Black"
                                   Grid.Column="2" Grid.Row="1"/>
                        </Grid>

                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>

        </ScrollViewer>


        <Border BorderBrush="Black" BorderThickness="1" MaxWidth="100" MaxHeight="100"
                HorizontalAlignment="Left"   VerticalAlignment="Bottom"  Margin="20"
                IsHitTestVisible="False">
            <Grid Background="White">
                <Viewbox StretchDirection="DownOnly" x:Name="viewBox" >

                    <ItemsControl ItemsSource="{Binding Path=Items}" BorderThickness="0" x:Name="small"
                             Width="{Binding Path=ActualWidth,ElementName=full,Mode=OneWay}"
                             Height="{Binding Path=ActualHeight,ElementName=full,Mode=OneWay}">
                        <ItemsControl.ItemsPanel>
                            <ItemsPanelTemplate>
                                <Canvas />
                            </ItemsPanelTemplate>
                        </ItemsControl.ItemsPanel>
                        <ItemsControl.ItemContainerStyle>
                            <Style TargetType="ContentPresenter">
                                <Setter Property="Canvas.Left" Value="{Binding Path=X,Mode=OneWay}" />
                                <Setter Property="Canvas.Top" Value="{Binding Path=Y,Mode=OneWay}" />
                                <Setter Property="Width" Value="{Binding Path=Width,Mode=OneWay}" />
                                <Setter Property="Height" Value="{Binding Path=Height,Mode=OneWay}" />
                            </Style>
                        </ItemsControl.ItemContainerStyle>
                        <ItemsControl.ItemTemplate>
                            <DataTemplate>
                                <Grid Background="{Binding Path=Color,Converter={StaticResource brushConverter}}"/>
                            </DataTemplate>
                        </ItemsControl.ItemTemplate>
                    </ItemsControl>

                </Viewbox>

                <Canvas VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
                    <Border BorderBrush="Red" BorderThickness="1" x:Name="redBox" />
                </Canvas>
            </Grid>
        </Border>

        <ScrollBar Minimum="100" Maximum="2000" HorizontalAlignment="Left" VerticalAlignment="Top" Width="200"  Orientation="Horizontal" Height="10" Margin="25,5,0,0"
                   Value="{Binding Path=CanvasWidth}"/>
        <ScrollBar Minimum="100" Maximum="2000" HorizontalAlignment="Left" VerticalAlignment="Top" Height="200"  Orientation="Vertical" Width="10" Margin="5,25,0,0"
                   Value="{Binding Path=CanvasHeight}"/>
    </Grid>
</Window>

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Media;
using System.ComponentModel;
using System.Collections.ObjectModel;
using System.Windows.Controls.Primitives;

namespace WpfApplication1
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            this.DataContext = Model.CreateTestModel();;
        }

        private void moveThumb_DragDelta(object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e)
        {
            var thumb = (Thumb)sender;
            FrameworkElement fe = (FrameworkElement)thumb.Tag;
            Canvas.SetLeft(fe, Canvas.GetLeft(fe) + e.HorizontalChange);
            Canvas.SetTop(fe, Canvas.GetTop(fe) + e.VerticalChange);
        }

        private void resizeThumb_DragDelta(object sender, DragDeltaEventArgs e)
        {
            var thumb = (Thumb)sender;
            FrameworkElement fe = (FrameworkElement)thumb.Tag;
            fe.Width = Math.Max(0, fe.Width + e.HorizontalChange);
            fe.Height = Math.Max(0, fe.Height + e.VerticalChange);
        }

        private void ScrollViewer_ScrollChanged(object sender, ScrollChangedEventArgs e)
        {
            if (e.OriginalSource == sender)
            {
                if (e.ExtentHeight > 0)
                {
                    double scale = this.viewBox.ActualWidth / e.ExtentWidth;

                    redBox.Width = scale * e.ViewportWidth;
                    redBox.Height = scale * e.ViewportHeight;
                    Canvas.SetLeft(redBox, scale * e.HorizontalOffset);
                    Canvas.SetTop(redBox, scale * e.VerticalOffset);
                }
                else
                {
                    redBox.Width = 0;
                    redBox.Height = 0;
                }
            }
        }
    }

    class Model : ModelBase
    {

        public static Model CreateTestModel()
        {
            Model m = new Model();

            double maxx = m.CanvasWidth;
            double maxy = m.CanvasHeight;

            Random rnd = new Random();
            byte[] bs = new byte[3];
            for (int i = 0; i < 10; i++)
            {
                Item item = new Item();
                item.X = m.CanvasWidth * rnd.NextDouble();
                item.Y = m.CanvasHeight * rnd.NextDouble();
                item.Width = 10 + m.CanvasWidth * 0.1 * rnd.NextDouble();
                item.Height = 10 + m.CanvasWidth * 0.1 * rnd.NextDouble();
                rnd.NextBytes(bs);
                item.Color = Color.FromRgb(bs[0], bs[1], bs[2]);

                item.Text = "Item-" + i.ToString();


                maxx = Math.Max(item.X + item.Width, maxx);
                maxy = Math.Max(item.Y + item.Height, maxy);

                m.Items.Add(item);
            }

            m.CanvasWidth = maxx;
            m.CanvasHeight = maxy;
            return m;
        }

        public Model()
        {
            CanvasWidth = 1000;
            CanvasHeight = 500;

            Items = new ObservableCollection<Item>();
        }
        public double CanvasWidth
        {
            get { return _CanvasWidth; }
            set { if (_CanvasWidth != value) { _CanvasWidth = value; OnPropertyChanged("CanvasWidth"); } }
        }
        private double _CanvasWidth;

        public double CanvasHeight
        {
            get { return _CanvasHeight; }
            set { if (_CanvasHeight != value) { _CanvasHeight = value; OnPropertyChanged("CanvasHeight"); } }
        }
        private double _CanvasHeight;

        public ObservableCollection<Item> Items { get; private set; }
    }

    class Item : ModelBase
    {
        public string Text
        {
            get { return _Text; }
            set { if (_Text != value) { _Text = value; OnPropertyChanged("Text"); } }
        }
        private string _Text;

        public double X
        {
            get { return _X; }
            set { if (_X != value) { _X = value; OnPropertyChanged("X"); } }
        }
        private double _X;

        public double Y
        {
            get { return _Y; }
            set { if (_Y != value) { _Y = value; OnPropertyChanged("Y"); } }
        }
        private double _Y;

        public double Width
        {
            get { return _Width; }
            set { if (_Width != value) { _Width = value; OnPropertyChanged("Width"); } }
        }
        private double _Width;

        public double Height
        {
            get { return _Height; }
            set { if (_Height != value) { _Height = value; OnPropertyChanged("Height"); } }
        }
        private double _Height;


        public Color Color
        {
            get { return _Color; }
            set { if (_Color != value) { _Color = value; OnPropertyChanged("Color"); } }
        }
        private Color _Color;
    }


    class ModelBase : INotifyPropertyChanged
    {

        public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
        protected virtual void OnPropertyChanged(string name)
        {
            var pc = PropertyChanged;
            if (pc != null)
            {
                pc(this, new System.ComponentModel.PropertyChangedEventArgs(name));
            }
        }
    }

    class SolidBrushConverter : IValueConverter
    {

        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return new SolidColorBrush((Color)value);
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return ((SolidColorBrush)value).Color;
        }
    }
}


这篇关于如何建立一个大画布的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆