Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/301.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# 如何让ListBox、Canvas和Thumb一起工作?_C#_Wpf_Wpf Controls - Fatal编程技术网

C# 如何让ListBox、Canvas和Thumb一起工作?

C# 如何让ListBox、Canvas和Thumb一起工作?,c#,wpf,wpf-controls,C#,Wpf,Wpf Controls,如何让ListBox、Canvas和Thumb一起工作 我试图将ListBox的选择逻辑与包含可拖动拇指的画布一起重用 不幸的是,拇指似乎可以处理鼠标事件,因此单击拇指不会使项目处于选中状态 我希望这些元素可以一起工作,而不必求助于程序代码中的变通方法。如果有人知道这是否可能或如何做到,请告诉我 下面是代码示例 在XAML中,我定义ListBox并指定画布作为ItemsPanel: <Window x:Class="ListBoxCanvasThumb.Window1" xmlns

如何让ListBox、Canvas和Thumb一起工作

我试图将ListBox的选择逻辑与包含可拖动拇指的画布一起重用

不幸的是,拇指似乎可以处理鼠标事件,因此单击拇指不会使项目处于选中状态

我希望这些元素可以一起工作,而不必求助于程序代码中的变通方法。如果有人知道这是否可能或如何做到,请告诉我

下面是代码示例

在XAML中,我定义ListBox并指定画布作为ItemsPanel:

<Window x:Class="ListBoxCanvasThumb.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300"
    Loaded="Window_Loaded"
    >
    <Grid>
        <ListBox
            x:Name="listBox"
            >
            <ListBox.ItemsPanel>
                <ItemsPanelTemplate>                
                    <Canvas />
                </ItemsPanelTemplate>
            </ListBox.ItemsPanel>
        </ListBox>
    </Grid>
</Window>
在DragDelta事件处理程序中,我更新项目在画布中的位置:

void thumb_DragDelta(object sender, DragDeltaEventArgs e)
{
    ListBoxItem i = (ListBoxItem)((Thumb)sender).Parent;
    Canvas.SetLeft(i, Canvas.GetLeft(i) + e.HorizontalChange);
    Canvas.SetTop(i, Canvas.GetTop(i) + e.VerticalChange);
}

我不知道这是否会满足您不使用过程代码的要求,因为很明显您已经或者这只是一个复制示例

无论如何,为PreviewMouseDown向ListBoxItem添加一个处理程序,并在其中选择该项:

i.PreviewMouseDown += new MouseButtonEventHandler(LBI_PreviewMouseDown);

void LBI_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
    var lbi = (ListBoxItem)sender;
    lbi.IsSelected = true;
    lbi.Focus();
}

我不知道这是否会满足您不使用过程代码的要求,因为很明显您已经或者这只是一个复制示例

无论如何,为PreviewMouseDown向ListBoxItem添加一个处理程序,并在其中选择该项:

i.PreviewMouseDown += new MouseButtonEventHandler(LBI_PreviewMouseDown);

void LBI_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
    var lbi = (ListBoxItem)sender;
    lbi.IsSelected = true;
    lbi.Focus();
}

您可以尝试将拇指移动到ListBoxItem模板中,并使用拇指的焦点状态触发选择。默认情况下,Thumb不可聚焦,但可以将其打开

         <ListBox.ItemContainerStyle>
            <Style TargetType="{x:Type ListBoxItem}">
                <Setter Property="Canvas.Left" Value="10" />
                <Setter Property="Canvas.Top" Value="10" />
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type ListBoxItem}">
                            <Border x:Name="Bd" ...>
                                <DockPanel>
                                    <Thumb x:Name="dragger" DockPanel.Dock="Top" 
                                           Width="50" Height="20" Focusable="True"/>
                                    <ContentPresenter/>
                                </DockPanel>
                            </Border>
                            <ControlTemplate.Triggers>
                                <Trigger SourceName="dragger" Property="IsFocused" Value="True">
                                    <Setter Property="IsSelected" Value="True" />
                                </Trigger>
。。。

您可以尝试将拇指移动到ListBoxItem模板中,并使用拇指的焦点状态触发选择。默认情况下,Thumb不可聚焦,但可以将其打开

         <ListBox.ItemContainerStyle>
            <Style TargetType="{x:Type ListBoxItem}">
                <Setter Property="Canvas.Left" Value="10" />
                <Setter Property="Canvas.Top" Value="10" />
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type ListBoxItem}">
                            <Border x:Name="Bd" ...>
                                <DockPanel>
                                    <Thumb x:Name="dragger" DockPanel.Dock="Top" 
                                           Width="50" Height="20" Focusable="True"/>
                                    <ContentPresenter/>
                                </DockPanel>
                            </Border>
                            <ControlTemplate.Triggers>
                                <Trigger SourceName="dragger" Property="IsFocused" Value="True">
                                    <Setter Property="IsSelected" Value="True" />
                                </Trigger>
。。。

出于这个目的,使用拇指控件并没有给您带来多少好处,它在几个方面与您正在尝试的操作相冲突。我会把它处理掉的

只需拦截鼠标下移、鼠标移动和鼠标上移事件,就可以轻松拖动项目,无需拇指:

在“鼠标按下”中,设置拖动标志,注意当前位置,然后捕获鼠标 在鼠标移动中,如果拖动为真,则根据控件上鼠标位置与原始位置之间的差异更新Canvas.Left和Canvas.Top 在“鼠标向上”中,清除拖动标志并清除鼠标捕获
通过这样做,Thumb不会截获键盘和鼠标的点击,也不会弄乱列表框。

为此,Thumb控件的使用并没有给您带来太多好处,它在多个方面与您的尝试相冲突。我会把它处理掉的

只需拦截鼠标下移、鼠标移动和鼠标上移事件,就可以轻松拖动项目,无需拇指:

在“鼠标按下”中,设置拖动标志,注意当前位置,然后捕获鼠标 在鼠标移动中,如果拖动为真,则根据控件上鼠标位置与原始位置之间的差异更新Canvas.Left和Canvas.Top 在“鼠标向上”中,清除拖动标志并清除鼠标捕获
通过这样做,拇指将不会截获键盘和鼠标的点击,也不会弄乱你的列表框。

谢谢你的回答,但这基本上是我已经在做的事情。问题是我想做的远不止这些。例如,实现多个选择和键盘输入左键和右键,以这种方式更改选择将产生更多的程序代码。我开始这样做,但发现自己认为一定有更好的办法!顺便说一句,我在上面加载的Window_中使用的过程代码只是为了说明问题,我的真实代码数据将对象列表绑定到ItemSource,并使用DataTemplate填充列表框。感谢您的回答,但这基本上是我已经在做的事情。问题是我想做的远不止这些。例如,实现多个选择和键盘输入左键和右键,以这种方式更改选择将产生更多的程序代码。我开始这样做,但发现自己认为一定有更好的办法!顺便说一句,我在上面加载的Window_中使用的过程代码只是为了说明问题,我的真实代码数据将对象列表绑定到ItemSource,并使用DataTemplate填充列表框。这对我不起作用。仍然会抑制单击,并且列表框不会选择。你能修好它吗@AshleyDavis?这对我没用。仍然会抑制单击,并且列表框不会选择。你能修好它吗@AshleyDavis?