网格控件可点击和可选择

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);
    }
}

我想去哪里:

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);
    }

请注意,您必须将网格的背景 属性 设置为画笔才能触发鼠标事件。