网格控件可点击和可选择
Grid control clickable and selectable
我正在尝试制作一个 计划控件 有点像 Outlook.
我知道devexpress在他的库中有一个控件,但我不愿意为这个控件支付那么多(每年)。
现在我需要做的下一件事实际上是使 网格单元格可点击 。有人对此有 想法吗?
这是我要创建的办公室行为的图像:
这是我现在拥有的代码(请记住,稍后我会将其转换为动态响应的自定义控件)。
<Window x:Class="Ghostware.Scheduler.Example.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Ghostware.Scheduler.Example"
xmlns:scheduler="clr-namespace:Ghostware.Scheduler;assembly=Ghostware.Scheduler"
mc:Ignorable="d"
Title="MainWindow" Height="600" Width="800">
<Grid IsSharedSizeScope="True">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<!--<scheduler:Scheduler Margin="5" />-->
<local:BorderGrid Grid.Row="0">
<local:BorderGrid.ColumnDefinitions>
<ColumnDefinition Width="60" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="17" />
</local:BorderGrid.ColumnDefinitions>
<local:BorderGrid.RowDefinitions>
<RowDefinition Height="22" />
<RowDefinition MinHeight="22" />
<RowDefinition Height="2" />
</local:BorderGrid.RowDefinitions>
<StackPanel Grid.Row="0" Grid.Column="1" Background="LightBlue">
<TextBlock Text="Monday 11 July" TextAlignment="Center" />
</StackPanel>
<StackPanel Grid.Row="0" Grid.Column="2" Background="LightBlue">
<TextBlock Text="12 July" TextAlignment="Center" />
</StackPanel>
<StackPanel Grid.Row="0" Grid.Column="3" Background="LightBlue">
<TextBlock Text="13 July" TextAlignment="Center" />
</StackPanel>
<StackPanel Grid.Row="0" Grid.Column="4" Background="LightBlue">
<TextBlock Text="14 July" TextAlignment="Center" />
</StackPanel>
<StackPanel Grid.Row="0" Grid.Column="5" Background="LightBlue">
<TextBlock Text="15 July" TextAlignment="Center" />
</StackPanel>
<StackPanel Grid.Row="0" Grid.Column="6" Background="LightBlue"></StackPanel>
<StackPanel Grid.Row="1" Grid.Column="1" Background="LightGray"></StackPanel>
<StackPanel Grid.Row="1" Grid.Column="2" Background="LightGray"></StackPanel>
<StackPanel Grid.Row="1" Grid.Column="3" Background="LightGray"></StackPanel>
<StackPanel Grid.Row="1" Grid.Column="4" Background="LightGray"></StackPanel>
<StackPanel Grid.Row="1" Grid.Column="5" Background="LightGray"></StackPanel>
<StackPanel Grid.Row="1" Grid.Column="6" Background="LightGray"></StackPanel>
</local:BorderGrid>
<ScrollViewer Grid.Row="1">
<local:BorderGrid>
<local:BorderGrid.ColumnDefinitions>
<ColumnDefinition Width="60" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</local:BorderGrid.ColumnDefinitions>
<local:BorderGrid.RowDefinitions>
<RowDefinition Height="44" />
<RowDefinition Height="44" />
<RowDefinition Height="44" />
<RowDefinition Height="44" />
<RowDefinition Height="44" />
<RowDefinition Height="44" />
<RowDefinition Height="44" />
<RowDefinition Height="44" />
<RowDefinition Height="44" />
<RowDefinition Height="44" />
<RowDefinition Height="44" />
<RowDefinition Height="44" />
<RowDefinition Height="44" />
<RowDefinition Height="44" />
<RowDefinition Height="44" />
<RowDefinition Height="44" />
</local:BorderGrid.RowDefinitions>
<TextBlock Text="00 00" Grid.Row="1" Grid.Column="0" TextAlignment="Right" Margin="0,2,5,0" />
<TextBlock Text="01 00" Grid.Row="3" Grid.Column="0" TextAlignment="Right" Margin="0,2,5,0" />
<TextBlock Text="02 00" Grid.Row="5" Grid.Column="0" TextAlignment="Right" Margin="0,2,5,0" />
<TextBlock Text="03 00" Grid.Row="7" Grid.Column="0" TextAlignment="Right" Margin="0,2,5,0" />
<TextBlock Text="04 00" Grid.Row="9" Grid.Column="0" TextAlignment="Right" Margin="0,2,5,0" />
<TextBlock Text="05 00" Grid.Row="11" Grid.Column="0" TextAlignment="Right" Margin="0,2,5,0" />
<StackPanel Grid.Row="3" Grid.Column="2" Grid.RowSpan="5" Background="Red" Margin="0,0,20,0" />
</local:BorderGrid>
</ScrollViewer>
</Grid>
</Window>
bordergrid 文件:
public class BorderGrid : Grid
{
protected override void OnRender(DrawingContext dc)
{
double leftOffset = 0;
double topOffset = 0;
Pen pen = new Pen(Brushes.Gray, 0.5);
pen.Freeze();
foreach (RowDefinition row in RowDefinitions)
{
dc.DrawLine(pen, new Point(0, topOffset), new Point(this.ActualWidth, topOffset));
topOffset += row.ActualHeight;
}
foreach (ColumnDefinition column in ColumnDefinitions)
{
dc.DrawLine(pen, new Point(leftOffset, 0), new Point(leftOffset, ActualHeight));
leftOffset += column.ActualWidth;
}
base.OnRender(dc);
}
}
我想去哪里:
- 我有一个 public github,所有代码都已打开。 (目前在 other-approach 分支机构工作)。 GITHUB
- 当我完成后,我想制作一个 nuget 包(目前没有针对计划的开源解决方案)。
Now the next thing that I need to do is actually make the grid cells clickable. Does anybody have an idea on doing that?
您可以覆盖 OnMouseDown
方法,使用此处的解决方案获取鼠标指针相对于 Grid
的位置:
Get Grid Cell by mouse click
然后您可以在相应的单元格中插入一个元素。请参考以下示例代码。
public class BorderGrid : Grid
{
public BorderGrid()
{
Background = Brushes.Transparent;
}
protected override void OnRender(DrawingContext dc)
{
double leftOffset = 0;
double topOffset = 0;
Pen pen = new Pen(Brushes.Gray, 0.5);
pen.Freeze();
foreach (RowDefinition row in RowDefinitions)
{
dc.DrawLine(pen, new Point(0, topOffset), new Point(this.ActualWidth, topOffset));
topOffset += row.ActualHeight;
}
foreach (ColumnDefinition column in ColumnDefinitions)
{
dc.DrawLine(pen, new Point(leftOffset, 0), new Point(leftOffset, ActualHeight));
leftOffset += column.ActualWidth;
}
base.OnRender(dc);
}
protected override void OnMouseDown(MouseButtonEventArgs e)
{
base.OnMouseDown(e);
Point point = Mouse.GetPosition(this);
int row = 0;
int col = 0;
double accumulatedHeight = 0.0;
double accumulatedWidth = 0.0;
foreach (var rowDefinition in RowDefinitions)
{
accumulatedHeight += rowDefinition.ActualHeight;
if (accumulatedHeight >= point.Y)
break;
row++;
}
foreach (var columnDefinition in ColumnDefinitions)
{
accumulatedWidth += columnDefinition.ActualWidth;
if (accumulatedWidth >= point.X)
break;
col++;
}
//color cell Red:
Grid childGrid = new Grid();
childGrid.Background = Brushes.Red;
Grid.SetColumn(childGrid, col);
Grid.SetRow(childGrid, row);
Children.Add(childGrid);
}
请注意,您必须将网格的背景 属性 设置为画笔才能触发鼠标事件。
我正在尝试制作一个 计划控件 有点像 Outlook.
我知道devexpress在他的库中有一个控件,但我不愿意为这个控件支付那么多(每年)。
现在我需要做的下一件事实际上是使 网格单元格可点击 。有人对此有 想法吗?
这是我要创建的办公室行为的图像:
这是我现在拥有的代码(请记住,稍后我会将其转换为动态响应的自定义控件)。
<Window x:Class="Ghostware.Scheduler.Example.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Ghostware.Scheduler.Example"
xmlns:scheduler="clr-namespace:Ghostware.Scheduler;assembly=Ghostware.Scheduler"
mc:Ignorable="d"
Title="MainWindow" Height="600" Width="800">
<Grid IsSharedSizeScope="True">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<!--<scheduler:Scheduler Margin="5" />-->
<local:BorderGrid Grid.Row="0">
<local:BorderGrid.ColumnDefinitions>
<ColumnDefinition Width="60" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="17" />
</local:BorderGrid.ColumnDefinitions>
<local:BorderGrid.RowDefinitions>
<RowDefinition Height="22" />
<RowDefinition MinHeight="22" />
<RowDefinition Height="2" />
</local:BorderGrid.RowDefinitions>
<StackPanel Grid.Row="0" Grid.Column="1" Background="LightBlue">
<TextBlock Text="Monday 11 July" TextAlignment="Center" />
</StackPanel>
<StackPanel Grid.Row="0" Grid.Column="2" Background="LightBlue">
<TextBlock Text="12 July" TextAlignment="Center" />
</StackPanel>
<StackPanel Grid.Row="0" Grid.Column="3" Background="LightBlue">
<TextBlock Text="13 July" TextAlignment="Center" />
</StackPanel>
<StackPanel Grid.Row="0" Grid.Column="4" Background="LightBlue">
<TextBlock Text="14 July" TextAlignment="Center" />
</StackPanel>
<StackPanel Grid.Row="0" Grid.Column="5" Background="LightBlue">
<TextBlock Text="15 July" TextAlignment="Center" />
</StackPanel>
<StackPanel Grid.Row="0" Grid.Column="6" Background="LightBlue"></StackPanel>
<StackPanel Grid.Row="1" Grid.Column="1" Background="LightGray"></StackPanel>
<StackPanel Grid.Row="1" Grid.Column="2" Background="LightGray"></StackPanel>
<StackPanel Grid.Row="1" Grid.Column="3" Background="LightGray"></StackPanel>
<StackPanel Grid.Row="1" Grid.Column="4" Background="LightGray"></StackPanel>
<StackPanel Grid.Row="1" Grid.Column="5" Background="LightGray"></StackPanel>
<StackPanel Grid.Row="1" Grid.Column="6" Background="LightGray"></StackPanel>
</local:BorderGrid>
<ScrollViewer Grid.Row="1">
<local:BorderGrid>
<local:BorderGrid.ColumnDefinitions>
<ColumnDefinition Width="60" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</local:BorderGrid.ColumnDefinitions>
<local:BorderGrid.RowDefinitions>
<RowDefinition Height="44" />
<RowDefinition Height="44" />
<RowDefinition Height="44" />
<RowDefinition Height="44" />
<RowDefinition Height="44" />
<RowDefinition Height="44" />
<RowDefinition Height="44" />
<RowDefinition Height="44" />
<RowDefinition Height="44" />
<RowDefinition Height="44" />
<RowDefinition Height="44" />
<RowDefinition Height="44" />
<RowDefinition Height="44" />
<RowDefinition Height="44" />
<RowDefinition Height="44" />
<RowDefinition Height="44" />
</local:BorderGrid.RowDefinitions>
<TextBlock Text="00 00" Grid.Row="1" Grid.Column="0" TextAlignment="Right" Margin="0,2,5,0" />
<TextBlock Text="01 00" Grid.Row="3" Grid.Column="0" TextAlignment="Right" Margin="0,2,5,0" />
<TextBlock Text="02 00" Grid.Row="5" Grid.Column="0" TextAlignment="Right" Margin="0,2,5,0" />
<TextBlock Text="03 00" Grid.Row="7" Grid.Column="0" TextAlignment="Right" Margin="0,2,5,0" />
<TextBlock Text="04 00" Grid.Row="9" Grid.Column="0" TextAlignment="Right" Margin="0,2,5,0" />
<TextBlock Text="05 00" Grid.Row="11" Grid.Column="0" TextAlignment="Right" Margin="0,2,5,0" />
<StackPanel Grid.Row="3" Grid.Column="2" Grid.RowSpan="5" Background="Red" Margin="0,0,20,0" />
</local:BorderGrid>
</ScrollViewer>
</Grid>
</Window>
bordergrid 文件:
public class BorderGrid : Grid
{
protected override void OnRender(DrawingContext dc)
{
double leftOffset = 0;
double topOffset = 0;
Pen pen = new Pen(Brushes.Gray, 0.5);
pen.Freeze();
foreach (RowDefinition row in RowDefinitions)
{
dc.DrawLine(pen, new Point(0, topOffset), new Point(this.ActualWidth, topOffset));
topOffset += row.ActualHeight;
}
foreach (ColumnDefinition column in ColumnDefinitions)
{
dc.DrawLine(pen, new Point(leftOffset, 0), new Point(leftOffset, ActualHeight));
leftOffset += column.ActualWidth;
}
base.OnRender(dc);
}
}
我想去哪里:
- 我有一个 public github,所有代码都已打开。 (目前在 other-approach 分支机构工作)。 GITHUB
- 当我完成后,我想制作一个 nuget 包(目前没有针对计划的开源解决方案)。
Now the next thing that I need to do is actually make the grid cells clickable. Does anybody have an idea on doing that?
您可以覆盖 OnMouseDown
方法,使用此处的解决方案获取鼠标指针相对于 Grid
的位置:
Get Grid Cell by mouse click
然后您可以在相应的单元格中插入一个元素。请参考以下示例代码。
public class BorderGrid : Grid
{
public BorderGrid()
{
Background = Brushes.Transparent;
}
protected override void OnRender(DrawingContext dc)
{
double leftOffset = 0;
double topOffset = 0;
Pen pen = new Pen(Brushes.Gray, 0.5);
pen.Freeze();
foreach (RowDefinition row in RowDefinitions)
{
dc.DrawLine(pen, new Point(0, topOffset), new Point(this.ActualWidth, topOffset));
topOffset += row.ActualHeight;
}
foreach (ColumnDefinition column in ColumnDefinitions)
{
dc.DrawLine(pen, new Point(leftOffset, 0), new Point(leftOffset, ActualHeight));
leftOffset += column.ActualWidth;
}
base.OnRender(dc);
}
protected override void OnMouseDown(MouseButtonEventArgs e)
{
base.OnMouseDown(e);
Point point = Mouse.GetPosition(this);
int row = 0;
int col = 0;
double accumulatedHeight = 0.0;
double accumulatedWidth = 0.0;
foreach (var rowDefinition in RowDefinitions)
{
accumulatedHeight += rowDefinition.ActualHeight;
if (accumulatedHeight >= point.Y)
break;
row++;
}
foreach (var columnDefinition in ColumnDefinitions)
{
accumulatedWidth += columnDefinition.ActualWidth;
if (accumulatedWidth >= point.X)
break;
col++;
}
//color cell Red:
Grid childGrid = new Grid();
childGrid.Background = Brushes.Red;
Grid.SetColumn(childGrid, col);
Grid.SetRow(childGrid, row);
Children.Add(childGrid);
}
请注意,您必须将网格的背景 属性 设置为画笔才能触发鼠标事件。