Модераторы: gambit, Kefir, Partizan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как добавить сетку на Canvas в WPF? 
V
    Опции темы
Anyone
Дата 24.7.2009, 10:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 218
Регистрация: 1.6.2008

Репутация: нет
Всего: нет




Пишу контрол, производный от Canvas. Необходимо добавить сетку с возможностью изменения шага по горизонтали и вертикали(в виде точек желательно, накрайняк, пунктирных линий), к которой возможна привязка элементов Canvas'а. 
Ничего подобного я не нашел, потому хотел бы спросить каким образом лучше всего поступить?

Может быть лучше всего рисовать ее при обновлении Canvas'a (если да, то куда копать)?

Также есть другая идея - использовать Grid и выставить свойство ShowGridLines="True":
Код

<local:UgeDrawingCanvas x:Name="DrawingCanvas">
    <Grid Name="DrawingCanvasGrid" ShowGridLines="True" Width="{Binding DrawingCanvas.ActualWidth}" Height="{Binding DrawingCanvas.ActualHeight}"/>
</local:UgeDrawingCanvas>
 
Но этот вариант мне не нравится, потому что выходит очень не красиво, размеры ячеек немного колеблятся в зависимости от положения скроллов, снизу и справа иногда не прорисовывается сетка.
Смещаю таким образом:
Код

        private void ScrollBarHorisontal_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            Dx = - e.NewValue;
            SetScrollOffset(Dx, Dy);
        }

        private void ScrollBarVertical_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            Dy = - e.NewValue;
            SetScrollOffset(Dx, Dy);
        }
        private void SetScrollOffset(double dx, double dy)
        {
            foreach (var item in DrawingCanvas.Children)
            {
                DrawingCanvasGrid.SetValue(RenderTransformProperty, new TranslateTransform(dx%gridX, dy%gridY));

                UIElement uiElement = item as UIElement;
                if (uiElement != null)
                {
                    uiElement.SetValue(RenderTransformProperty,new TranslateTransform(dx,dy));
                }
            }
        }


И еще один вопрос, как можно изменить вид линий грида? хочу вообще заменить на точки.

Есть другие идеи?
PM MAIL   Вверх
Partizan
Дата 24.7.2009, 20:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Let's do some .NET
****


Профиль
Группа: Модератор
Сообщений: 2828
Регистрация: 19.12.2005
Где: Санкт-Петербург

Репутация: 9
Всего: 67



Anyone, ага...можно попробовать собственный adorner реализовать, в котором и отрисовывать соответствующую сетку линиями


--------------------
СУВ,
       Partizan.
PM MAIL WWW ICQ Skype GTalk Jabber   Вверх
Anyone
Дата 27.7.2009, 12:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 218
Регистрация: 1.6.2008

Репутация: нет
Всего: нет



Цитата(Partizan @  24.7.2009,  20:31 Найти цитируемый пост)
ожно попробовать собственный adorner реализовать

Но при этом же сетка будет всегда сверху скорее всего... В принципе, если в виде точек ее реализовать, тоже не плохо, но думаю не всегда такое поведение желательно. Попробую, идея мне нравится.
PM MAIL   Вверх
rooks
Дата 28.7.2009, 01:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 90
Регистрация: 28.9.2008
Где: Минск

Репутация: 5
Всего: 9



а как насчет сделать бэкграунд с помощью DrawingBrush?
Код
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Page.Resources>
        <DrawingBrush x:Key="stripedBrush" Viewport="0,0,10,10" ViewportUnits="Absolute" TileMode="Tile">
            <DrawingBrush.Drawing>
                <GeometryDrawing Brush="Black">
                    <GeometryDrawing.Geometry>
                        <GeometryGroup FillRule="EvenOdd">
                            <RectangleGeometry Rect="0,0,10,10" />
                            <PathGeometry Figures="M 0,0 L 1,0 L 1,1 L 0,1z"/>
                            <RectangleGeometry Rect="0,0,10,10" />
                        </GeometryGroup>
                    </GeometryDrawing.Geometry>
                </GeometryDrawing>
            </DrawingBrush.Drawing>
        </DrawingBrush>
    </Page.Resources>
    <Grid Background="{StaticResource stripedBrush}">
    
    </Grid>
</Page>


Это сообщение отредактировал(а) rooks - 28.7.2009, 01:38
PM MAIL ICQ   Вверх
Anyone
Дата 28.7.2009, 08:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 218
Регистрация: 1.6.2008

Репутация: нет
Всего: нет



Цитата(rooks @  28.7.2009,  01:38 Найти цитируемый пост)
а как насчет сделать бэкграунд с помощью DrawingBrush?

А как в этом случае менять шаг сетки и смещать ее при прокрутке? Определить эти все свойства в моем производном классе а сетку определить в шаблоне с привязками к этим свойствам, или лучше програмно генерить и переприсваивать кисть? А вообще-то свойство Background мне еще пригодится для того чтоб задать фоновый рисунок или цвет, думаю заливать этой кистью какой-нить прямоугольник внутри канваса.

Это сообщение отредактировал(а) Anyone - 28.7.2009, 08:59
PM MAIL   Вверх
neiron
Дата 28.7.2009, 08:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 145
Регистрация: 18.4.2006
Где: Краснодар

Репутация: нет
Всего: 4



Шаг вполне можно менять скейлтрансформом. Хочешь увеличивай, хочешь уменьшай. скейл для самого Drawing, а не для канвы.
А смещать соответственно транслейтом
PM MAIL   Вверх
Anyone
Дата 28.7.2009, 09:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 218
Регистрация: 1.6.2008

Репутация: нет
Всего: нет



Большое спасибо за помощь. Видимо, создавать кисть - наилучший вариант.
PM MAIL   Вверх
Anyone
Дата 28.7.2009, 09:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 218
Регистрация: 1.6.2008

Репутация: нет
Всего: нет



Вот как я добавляю сетку:
Код

            <local:UgeDrawingCanvas x:Name="DrawingCanvas" Grid.Row="1" Grid.Column="1" Background="LightGray" ClipToBounds="True" SizeChanged="DrawingCanvas_SizeChanged">
            <Rectangle Name="DrawingCanvasGrid" Fill="{StaticResource stripedBrush}"/>
            </local:UgeDrawingCanvas>


И у меня пару вопросов:
1. Как сделать чтобы прямоугольник полностью залил всю область канваса?
2. Как с помощью ScaleTransform изменить шаг сетки так, чтобы размер точек оставался в 1 пиксел?
3. Как правильно использовать ScaleTransform для кисти? Для шага (25;50) я написал такой код:
Код

DrawingCanvasGrid.Fill.RelativeTransform = new ScaleTransform(5, 2.5);
 
Но при этом точки тоже отмасштабировались.
PM MAIL   Вверх
neiron
Дата 28.7.2009, 09:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 145
Регистрация: 18.4.2006
Где: Краснодар

Репутация: нет
Всего: 4



1. VerticalAligment = "Stretch" HorizontalAligment = "Stretch" для прямоугольника. Учитывая что он кистью отрисовывается - должен замостить канву.
2-3. Что-то в голову не приходит ничего простого. Только переопределение кисти. Операция не слишком трудозатратная, потому, думаю, латентности не добавит. кисти вроде бы freezable поддерживают - должны автоматом перерисовываться.
PM MAIL   Вверх
Anyone
Дата 28.7.2009, 09:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 218
Регистрация: 1.6.2008

Репутация: нет
Всего: нет



Цитата(neiron @  28.7.2009,  09:40 Найти цитируемый пост)
1. VerticalAligment = "Stretch" HorizontalAligment = "Stretch" для прямоугольника. 

В том то и дело, что не помогает... Наверное придется програмно по актульным размерам канваса, что не очень то и хочется...

Цитата(neiron @  28.7.2009,  09:40 Найти цитируемый пост)
2-3. Что-то в голову не приходит ничего простого. Только переопределение кисти.

Вот и мне только это приходит в голову.

Добавлено через 9 минут и 9 секунд
А можно в этом случае использовать привязки к свойствам владельца кисти?
Код

        <DrawingBrush x:Key="stripedBrush" Viewport="{TemplateBinding ...}" ViewportUnits="Absolute" TileMode="Tile">
            <DrawingBrush.Drawing>
                <GeometryDrawing Brush="{TemplateBinding ...}">
                    <GeometryDrawing.Geometry>
                        <GeometryGroup FillRule="EvenOdd">
                            <RectangleGeometry Rect="{TemplateBinding ...}" />
                            <PathGeometry Figures="M 0,0 L 1,0 L 1,1 L 0,1z"/>
                            <RectangleGeometry Rect="{TemplateBinding ...}" />
                        </GeometryGroup>
                    </GeometryDrawing.Geometry>
                </GeometryDrawing>
            </DrawingBrush.Drawing>
        </DrawingBrush>

Тогда все эти свойства можно будет определить в канвасе (прямоугольнике).
PM MAIL   Вверх
Anyone
Дата 28.7.2009, 13:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 218
Регистрация: 1.6.2008

Репутация: нет
Всего: нет



Попытался выполнить это с помощью стиля, но с привязкой данных ничего не получается (Brush="{Binding Stroke}"). 
Код

    <Style x:Key="DrawingCanvasGridStyle">
        <Setter Property="Rectangle.Fill">
            <Setter.Value>
                <DrawingBrush Viewport="0,0,50,50" ViewportUnits="Absolute" TileMode="Tile">
                    <DrawingBrush.Drawing>
                        <GeometryDrawing Brush="{Binding Stroke}">
                            <GeometryDrawing.Geometry>
                                <GeometryGroup FillRule="EvenOdd">
                                    <RectangleGeometry Rect="0,0,50,50" />
                                    <PathGeometry Figures="M 0,0 L 2,0 L 2,2 L 0,2z"/>
                                    <RectangleGeometry Rect="0,0,50,50" />
                                </GeometryGroup>
                            </GeometryDrawing.Geometry>
                        </GeometryDrawing>
                    </DrawingBrush.Drawing>
                </DrawingBrush>
            </Setter.Value>
        </Setter> 
    </Style>

Что я делаю не так?
PM MAIL   Вверх
Anyone
Дата 28.7.2009, 17:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 218
Регистрация: 1.6.2008

Репутация: нет
Всего: нет



Также попытался програмно создавать кисть, но ничего не получилось:

Код

        private DrawingBrush DefineBrush(double x, double y, int width, Color color)
        {
            GeometryDrawing geometryDrawing = new GeometryDrawing();
            RectangleGeometry rectangleGeometry 
                = new RectangleGeometry(new Rect(x / 2 - width, y / 2 - width, width, width));
            geometryDrawing.Geometry = rectangleGeometry;
            geometryDrawing.Brush = new SolidColorBrush(color);
            geometryDrawing.Pen=new Pen(new SolidColorBrush(color),1);

            return new DrawingBrush(geometryDrawing);
        }

PM MAIL   Вверх
Anyone
Дата 29.7.2009, 09:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 218
Регистрация: 1.6.2008

Репутация: нет
Всего: нет



Решил задачу с помощью програмной кисти. 
Всем спасибо за помощь. 
Правда хотелось бы еще попробывать с помощью шаблона\стиля, буду благодарен за подсказку по поводу привязки параметров кисти к свойствам контрола.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | WPF и Silverlight | Следующая тема »


 




[ Время генерации скрипта: 0.1370 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.