У меня есть <Grid>
, который содержит несколько вертикальных и горизонтальных <Line>
. Я хочу, чтобы сетка масштабировалась в соответствии с размером окна и сохраняла свое соотношение сторон, поэтому она содержится в <Viewbox Stretch="Uniform">
.
Однако я также хочу, чтобы линии всегда отображались с шириной в 1 пиксель, поэтому я использую:
Line line = new Line();
line.SetValue(RenderOptions.EdgeModeProperty, EdgeMode.Aliased);
// other line settings here...
Это делает первоначальный вид линий идеальным, но как только вы начинаете изменять размер окна, срабатывает растяжение / масштабирование, и линии снова становятся смесью толщиной 1 и 2 пикселя.
Есть ли способ, чтобы линии всегда были толщиной в 1 пиксель, а также позволяли изменять размер окна / сетки?
Обновление - использование геометрии пути в соответствии с предложением Клеменса
@Clemens - Спасибо за выделение различий в рендеринге между линиями и контурами. Когда я пытаюсь переработать свой код, используя ваш пример, у меня возникает то слабое чувство, что я копаю для себя больше дыр и не совсем понимаю всю концепцию (полностью моя вина, а не ваша, я просто новичок в WPF) .
Я добавлю несколько снимков экрана, чтобы проиллюстрировать следующее описание:
Я делаю игровую доску (для игры в Go, если это поможет разобраться в раскладке вообще). У меня есть сетка 9x9, и я планирую разместить игровые элементы, просто добавив эллипс к определенной ячейке сетки.
Однако, чтобы нарисовать основные линии на доске, мне нужно нарисовать линии, пересекающие середину ячеек по всей доске (в Go фигуры размещаются на пересечениях, а не в середине ячеек).
Вполне возможно, что я использую совершенно неправильный подход, пожалуйста, не стесняйтесь сказать мне, чтобы я начал снова по другому пути, а не взламывал текущую структуру.
Вот как я это делал до сих пор (я добавляю пути программно из-за способа вычисления координат. Не уверен, что все это можно сделать в XAML):
XAML:
<Grid MinHeight="400" MinWidth="400" ShowGridLines="False" x:Name="boardGrid">
<Grid.Resources>
<ScaleTransform x:Key="transform"
ScaleX="{Binding ActualWidth, ElementName=boardGrid}"
ScaleY="{Binding ActualHeight, ElementName=boardGrid}" />
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<!-- more rows, 9 in total -->
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<!-- more columns, 9 in total -->
</Grid.ColumnDefinitions>
<!-- example game pieces -->
<Ellipse Stroke="Black" Fill="#333333" Grid.Row="3" Grid.Column="2" />
<Ellipse Stroke="#777777" Fill="#FFFFFF" Grid.Row="4" Grid.Column="4" />
</Grid>
C#:
int cols = 9;
int rows = 9;
// Draw horizontal lines
for (int row = 0; row < rows; row++)
{
var path = new System.Windows.Shapes.Path();
path.Stroke = Brushes.Black;
path.StrokeThickness = 1;
path.SetValue(RenderOptions.EdgeModeProperty, EdgeMode.Aliased);
Grid.SetRow(path, row);
Grid.SetColumnSpan(path, cols);
Grid.SetZIndex(path, -1);
double cellWidth = boardGrid.ColumnDefinitions[0].ActualWidth;
double cellHeight = boardGrid.RowDefinitions[0].ActualHeight;
double x1 = (cellWidth / 2) / boardGrid.ActualWidth;
double y1 = (cellHeight / 2) / boardGrid.ActualHeight;
double x2 = ((cellWidth * cols) - (cellWidth / 2)) / boardGrid.ActualWidth;
double y2 = (cellHeight / 2) / boardGrid.ActualHeight;
path.Data = new LineGeometry(new Point(x1, y1),
new Point(x2, y2),
(ScaleTransform)boardGrid.TryFindResource("transform"));
boardGrid.Children.Add(path);
}
// Similar loop code follows for vertical lines...
Это то, что я получаю при использовании приведенного выше кода
Я хочу, чтобы это выглядело примерно так. У меня возникло еще 2 вопроса:
1) Правильно ли я использую подход, когда вычисляю значения x1
, x2
, y1
и y2
путем деления их на общую ширину доски для создания числа от 0 до 1, чтобы затем к ним можно было применить ScaleTransform?
2) Теперь, когда я больше не использую Viewbox
, как мне выполнить масштабирование с фиксированным соотношением? Если я увеличиваю окно, доска растягивается непропорционально (см. Изображение ниже). (Хотя он больше не сглаживает строки, и это здорово.)
Я знаю, что это будет монолитный пост. Я очень благодарен за ваше терпение и ответы.