Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在scrollviewer画布上确定用户单击的集合_C#_Wpf_Xaml_Scrollviewer - Fatal编程技术网

C# 在scrollviewer画布上确定用户单击的集合

C# 在scrollviewer画布上确定用户单击的集合,c#,wpf,xaml,scrollviewer,C#,Wpf,Xaml,Scrollviewer,我在开发基于MVVM的WPF应用程序时遇到了一个小障碍 我的愿望是能够告诉用户希望查看什么“bin”,因为通常情况下,事件多于视图中显示的事件。这基本上是一个小的stackpanel,它是在代码后面开发的,显示在用户选择的箱子上方。详情如下 基本背景是: 我正在记录ViewModel中发生的事件,我将它们称为事件 我在时间线上的视图中将它们显示为50x50画布(每个事件一个)。这里的细微差别是,我的空间非常有限,因此我将实际显示的事件数量限制为3个堆栈,每个时间段的事件数量略有偏移(只需想象卡

我在开发基于MVVM的WPF应用程序时遇到了一个小障碍

我的愿望是能够告诉用户希望查看什么“bin”,因为通常情况下,事件多于视图中显示的事件。这基本上是一个小的stackpanel,它是在代码后面开发的,显示在用户选择的箱子上方。详情如下

基本背景是:

  • 我正在记录ViewModel中发生的事件,我将它们称为事件

  • 我在时间线上的视图中将它们显示为50x50画布(每个事件一个)。这里的细微差别是,我的空间非常有限,因此我将实际显示的事件数量限制为3个堆栈,每个时间段的事件数量略有偏移(只需想象卡片堆叠在后面,下面的卡片顶部和右侧被显示)

  • 在每一个时间点(每30秒),画布向左滚动75个像素,当然,所有绘制的元素也随之移动。这也为活动设置了“箱子”。基本上,0到29.9秒之间的所有时间都在0仓,30到59.9秒是1仓,以此类推

  • 我正在使用一个PreviewMouseLeftButtonDown事件,该事件链接到负责显示绑定事件的ItemsControl

就目前情况而言,一切正常。我可以收集鼠标点击,我一直在尝试使用一些基本的数学来确定点击了哪组事件。这是基于单击时鼠标的X位置,并考虑了ScrollViewer窗口的任何滚动。不幸的是,我没有得到一个正确的“垃圾桶”

我尝试过的其他事情:

  • 向canvas元素添加一个标记,其中包含关于它所属的容器的信息。这不起作用,因为我获取的代码中的ItemsSource包含所有事件,而不仅仅是单击的事件。这是我访问ItemsSource的方式

    private void ItemsControl_PreviewMouseLeftButtonDown( object sender, MouseButtonEventArds e)
    {
        var control = (ItemsControl)sender;
        var isource = control.ItemsSource;
        Debug.Assert(isource != null);
    }
    
  • 在将其放入itemscontrol之前,我尝试将其嵌套在stackpanel中。当我有一个嵌套的列表时,它就起作用了,但当我不再拥有列表列表时,它就崩溃了。我也不确定这是否是一个可行的选择

我为这篇文章准备的XAML(对于那些可能想看到它的人)如下所示:

感兴趣的主ItemsControl是最后一个,因为它包含用于在ScrollViewer的画布上绘制事件的datatemplate。另外两个只是我在时间线底部使用的时间戳

<UserControl 
    x:Class="Removed.Views.TransitionTimeline"
    x:ClassModifier="internal"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    mc:Ignorable="d" 
    d:DesignHeight="300" d:DesignWidth="300">
  <UserControl.Resources>
    <Style x:Key="ISTCanvasStyle" TargetType="Canvas">
      <Setter Property="Background" Value="Transparent" />
    </Style>

    <Style x:Key="ISTBorderStyle" TargetType="Border">
      <Setter Property="BorderThickness" Value="3" />
      <Setter Property="BorderBrush" Value="{Binding ColorBrush}" />
      <Setter Property="CornerRadius" Value="8" />
      <Setter Property="HorizontalAlignment" Value="Center" />
      <Setter Property="VerticalAlignment" Value="Center" />
      <Setter Property="Background" Value="#FF555555" />
      <Setter Property="Height" Value="50" />
      <Setter Property="Width" Value="50" />
    </Style>

    <Style x:Key="ISTTextBlockStyle" TargetType="TextBlock">
      <Setter Property="Text" Value="{Binding ShortName}" />
      <Setter Property="HorizontalAlignment" Value="Center" />
      <Setter Property="VerticalAlignment" Value="Center" />
      <Setter Property="FontWeight" Value="Bold" />
      <Setter Property="FontSize" Value="40" />
      <Setter Property="Foreground" Value="White" />
      <Setter Property="TextAlignment" Value="Center" />
    </Style>

    <Style x:Key="EventCountTextStyle" TargetType="TextBlock">
      <Setter Property="Text" Value="{Binding ExtraEvents}" />
      <Setter Property="Canvas.Top" Value="-15" />
      <Setter Property="Canvas.Left" Value="-25" />
      <Setter Property="FontWeight" Value="Bold" />
      <Setter Property="FontSize" Value="13" />
      <Setter Property="Foreground" Value="{Binding EventTextColorBrush}" />
      <Setter Property="TextAlignment" Value="Center" />
    </Style>

    <DataTemplate x:Key="IndividualStateTransitions">
      <Canvas Margin="{Binding Margin}" Style="{ StaticResource ISTCanvasStyle}" >
        <Border Canvas.Left="-12.5" Style="{ StaticResource ISTBorderStyle}" >
          <TextBlock Style="{StaticResource ISTTextBlockStyle}" />
        </Border>
        <TextBlock Style="{StaticResource EventCountTextStyle}" />
      </Canvas>
    </DataTemplate>

    <DataTemplate x:Key="IST">
      <ItemsControl
          ItemsSource="{Binding}" 
          ItemTemplate="{StaticResource IndividualStateTransitions}"
          PreviewMouseLeftButtonDown="ItemsControl_PreviewMouseLeftButtonDown"
          Width="75">
        <ItemsControl.ItemsPanel>
          <ItemsPanelTemplate>
            <Canvas />
          </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemContainerStyle>
          <Style TargetType="ContentPresenter">
            <Setter Property="Canvas.ZIndex" Value="{Binding ZIndex}" />
          </Style>
        </ItemsControl.ItemContainerStyle>
      </ItemsControl>
    </DataTemplate>

    <DataTemplate x:Key="BottomTimeBar">
      <Canvas>
        <Line X1="{Binding DashX}" X2="{Binding DashX}" Y1="100" Y2="0" Stroke="#FF646464" StrokeThickness="1" StrokeDashArray="5" StrokeDashCap="Round" />
        <TextBlock Canvas.ZIndex="-999"  Width="50" TextAlignment="Center" Text="{Binding TimerText}" Canvas.Left="{Binding BlockLeft}" 
                       Canvas.Top="85" Foreground="White" Background="#FF444444" FontSize="13" />
      </Canvas>
    </DataTemplate>

  </UserControl.Resources>
  <Grid Name="TimelineGrid" Height="192">
    <Grid.RowDefinitions>
      <RowDefinition Height="92" />
      <RowDefinition Height="100" />
    </Grid.RowDefinitions>

    <Canvas Grid.Row="0" Width="1920" Height="100">
      <ScrollViewer            
          Width="1920"
          Height="100"
          Name="_timelineScrollViewer2" 
          CanContentScroll="True" 
          Background="Transparent"
          HorizontalScrollBarVisibility="Hidden" 
          VerticalScrollBarVisibility="Hidden">
        <Canvas Width="9999" Name="_timelineCanvas2">
        </Canvas>
      </ScrollViewer>
    </Canvas>

    <Canvas Grid.Row="1" Name="MainCanvas" Width="1920" Height="100" >
      <Line X1="0" X2="1920" Y1="0" Y2="0" Stroke="#FFD0D0D0" StrokeThickness="3">
        <Line.Effect>
          <DropShadowEffect BlurRadius="3" ShadowDepth="3" />
        </Line.Effect>
      </Line>
      <Line X1="0" X2="1920" Y1="55" Y2="55" Stroke="#FFD0D0D0" StrokeThickness="3">
        <Line.Effect>
          <DropShadowEffect BlurRadius="3" ShadowDepth="3" />
        </Line.Effect>
      </Line>
      <ScrollViewer            
          Width="1920"
          Height="100"
          Name="_timelineScrollViewer" 
          CanContentScroll="True" 
          Background="Transparent"
          HorizontalScrollBarVisibility="Hidden" 
          VerticalScrollBarVisibility="Hidden"
          PreviewMouseLeftButtonDown="TimelineScrollViewerLeftMouseDown" 
          PreviewMouseLeftButtonUp="LeftMouseUp" 
          PreviewMouseMove="TimelineScrollViewerMouseMove"
          PreviewMouseWheel="TimelineScrollViewerPreviewMouseWheel"
          ScrollChanged="OnTimelineScrollChanged" ClipToBounds="False">
        <Canvas Width="9999" Name="_timelineCanvas">
          <Line Canvas.ZIndex="-1000" Name="CurrentTimeLine" X1="1280" X2="1280" Y1="0" Y2="100" Stroke="#FFD0D0D0" StrokeThickness="3">
            <Line.Effect>
              <DropShadowEffect BlurRadius="3" ShadowDepth="3" />
            </Line.Effect>
          </Line>
          <ItemsControl ItemsSource="{Binding BottomTimeBarData}" ItemTemplate="{StaticResource BottomTimeBar}" Canvas.Left="{Binding LeftScroll}">
            <ItemsControl.ItemsPanel>
              <ItemsPanelTemplate>
                <Canvas />
              </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
          </ItemsControl>
          <ItemsControl ItemsSource="{Binding BottomTimeBarDataPast}" ItemTemplate="{StaticResource BottomTimeBar}" Canvas.Left="{Binding LeftScroll}">
            <ItemsControl.ItemsPanel>
              <ItemsPanelTemplate>
                <Canvas />
              </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
          </ItemsControl>

          <ItemsControl ItemsSource="{Binding DisplayObject}" ItemTemplate="{StaticResource IndividualStateTransitions}" Canvas.Left="{Binding LeftScroll}" Canvas.Top="15" Margin="0.0, 25.5"
                        PreviewMouseLeftButtonDown="ItemsControl_PreviewMouseLeftButtonDown" >
            <ItemsControl.ItemsPanel>
              <ItemsPanelTemplate>
                <StackPanel />
              </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.ItemContainerStyle>
              <Style TargetType="ContentPresenter">
                <Setter Property="Canvas.ZIndex" Value="{Binding ZIndex}" />
              </Style>
            </ItemsControl.ItemContainerStyle>
          </ItemsControl>
        </Canvas>
      </ScrollViewer>
    </Canvas>
  </Grid>
</UserControl>
我订阅了一个事件聚合器,以便在发送事件时捕获它们。这将触发我的
oneventereceived
方法。关于这个方法,您需要知道的是,它从它接收的事件中获取信息,并根据事件发生的时间确定它应该落入哪个容器中。这会触发对my
DrawObject
方法的调用

如果您希望尝试并模拟这一点,您可以用一些硬编码的东西来代替stvm的使用。我无法提供这方面的实际数据。颜色只是一种表示事件类型的颜色。stvm.ShortName只是一个字母_bin只是一个
列表
,用于跟踪各个bin中发生的事件总数<代码>位置只是它所属箱子中的数字事件。因此,如果这是第一个事件,将是1。如果这是第十个项目,那将是10个

此处的
FindLastVisualChild
方法仅用于返回给定bin的第三个DisplayObject的位置索引。这允许我更新标记,该标记表示堆栈中存在“+X more.”事件

private void DrawObject( EventViewModel stvm, int position, int bin )
{
    var margin = "";
    var zindex = 0;
    var left = bin * 75.0;
    var textColor = Colors.Transparent;
    var extraEvents = "+ ";
    switch ( position )
    {
        case 1:
            left += 12.5;
            margin = left + ", -5";
            zindex = 3;
            DisplayObject.Add( new DisplayObjects
            {
                Color = stvm.Color,
                ShortName = stvm.ShortName,
                Margin = margin,
                ZIndex = zindex,
                EventTextColor = textColor,
                ExtraEvents = extraEvents,
                ElementBin = bin
            } );
            break;
        case 2:
            left += 22.5;
            margin = left + ", -15";
            zindex = 2;
            DisplayObject.Add( new DisplayObjects
            {
                Color = stvm.Color,
                ShortName = stvm.ShortName,
                Margin = margin,
                ZIndex = zindex,
                EventTextColor = textColor,
                ExtraEvents = extraEvents,
                ElementBin = bin
            } );
            break;
        case 3:
            left += 32.5;
            margin = left + ", -25";
            zindex = 1;
            DisplayObject.Add( new DisplayObjects 
            { 
                Color = stvm.Color, 
                ShortName = stvm.ShortName, 
                Margin = margin, 
                ZIndex = zindex, 
                EventTextColor = textColor, 
                ExtraEvents = extraEvents,
                ElementBin = bin
            } );
            break;
        default:
            //left += 32.5;
            //margin = left + ", -25";
            //DisplayObject.Add( new DisplayObjects { Color = stvm.Color, ShortName = stvm.ShortName, Margin = margin, ZIndex = zindex, EventTextColor = textColor, ExtraEvents = extraEvents } );
            extraEvents += ( _bins[bin] - 3 ) + " more.";
            var test = FindLastVisualChild( bin );
            DisplayObject[test].EventTextColor = Colors.White;
            DisplayObject[FindLastVisualChild( bin )].ExtraEvents = extraEvents;
            break;
    }
}

private int FindLastVisualChild( int bin )
{
    var sum = 0;
    for ( var idx = 0; idx <= bin; idx++ )
        if ( _bins[idx] <= 3 )
            sum += _bins[idx];
        else
            sum += 3;
    return ( sum - 1 );
}
private void DrawObject(EventViewModel stvm、int-position、int-bin)
{
var保证金=”;
var-zindex=0;
左变分=bin*75.0;
var textColor=颜色。透明;
var extraEvents=“+”;
开关(位置)
{
案例1:
左+=12.5;
边距=左+“,-5”;
zindex=3;
添加(新的显示对象)
{
Color=stvm.Color,
ShortName=stvm.ShortName,
保证金=保证金,
ZIndex=ZIndex,
EventTextColor=textColor,
外部事件=外部事件,
ElementBin=bin
} );
打破
案例2:
左+=22.5;
边距=左+“,-15”;
zindex=2;
添加(新的显示对象)
{
Color=stvm.Color,
ShortName=stvm.ShortName,
保证金=保证金,
ZIndex=ZIndex,
EventTextColor=textColor,
外部事件=外部事件,
ElementBin=bin
} );
打破
案例3:
左+=32.5;
边距=左+“,-25”;
zindex=1;
添加(新的显示对象)
{ 
Color=stvm.Color,
ShortName=stvm.ShortName,
保证金=保证金,
ZIndex=ZIndex,
EventTextColor=textColor,
外部事件=外部事件,
ElementBin=bin
} );
打破
违约:
//左+=32.5;
//边距=左+“,-25”;
//添加(新的显示对象{Color=stvm.Color,ShortName=stvm.ShortName,Margin=Margin,ZIndex=ZIndex,EventTextColor=textColor,ExtraEvents=ExtraEvents});
外部事件+=(\u bin[bin]-3)+“更多。”;
var测试=FindLastVisualChild(bin);
显示
private void DrawObject( EventViewModel stvm, int position, int bin )
{
    var margin = "";
    var zindex = 0;
    var left = bin * 75.0;
    var textColor = Colors.Transparent;
    var extraEvents = "+ ";
    switch ( position )
    {
        case 1:
            left += 12.5;
            margin = left + ", -5";
            zindex = 3;
            DisplayObject.Add( new DisplayObjects
            {
                Color = stvm.Color,
                ShortName = stvm.ShortName,
                Margin = margin,
                ZIndex = zindex,
                EventTextColor = textColor,
                ExtraEvents = extraEvents,
                ElementBin = bin
            } );
            break;
        case 2:
            left += 22.5;
            margin = left + ", -15";
            zindex = 2;
            DisplayObject.Add( new DisplayObjects
            {
                Color = stvm.Color,
                ShortName = stvm.ShortName,
                Margin = margin,
                ZIndex = zindex,
                EventTextColor = textColor,
                ExtraEvents = extraEvents,
                ElementBin = bin
            } );
            break;
        case 3:
            left += 32.5;
            margin = left + ", -25";
            zindex = 1;
            DisplayObject.Add( new DisplayObjects 
            { 
                Color = stvm.Color, 
                ShortName = stvm.ShortName, 
                Margin = margin, 
                ZIndex = zindex, 
                EventTextColor = textColor, 
                ExtraEvents = extraEvents,
                ElementBin = bin
            } );
            break;
        default:
            //left += 32.5;
            //margin = left + ", -25";
            //DisplayObject.Add( new DisplayObjects { Color = stvm.Color, ShortName = stvm.ShortName, Margin = margin, ZIndex = zindex, EventTextColor = textColor, ExtraEvents = extraEvents } );
            extraEvents += ( _bins[bin] - 3 ) + " more.";
            var test = FindLastVisualChild( bin );
            DisplayObject[test].EventTextColor = Colors.White;
            DisplayObject[FindLastVisualChild( bin )].ExtraEvents = extraEvents;
            break;
    }
}

private int FindLastVisualChild( int bin )
{
    var sum = 0;
    for ( var idx = 0; idx <= bin; idx++ )
        if ( _bins[idx] <= 3 )
            sum += _bins[idx];
        else
            sum += 3;
    return ( sum - 1 );
}
var canvas = e.OriginalSource as Canvas
var item = canvas.DataContext as MyItemViewModel;
var control = (Canvas)sender;
var item = control.DataContext as DisplayObjects;
var itembin = item.ElementBin;