简体   繁体   English

WPF ListBox DataTemplate鼠标在里面

[英]WPF ListBox DataTemplate Mouse inside

I have a ListBox control and some DataTemplates for the ListBox: 我有一个ListBox控件和一些用于ListBox的DataTemplates:

<DataTemplate DataType="{x:Type local:LogEntry}" x:Key="lineNumberTemplate">
  <Grid IsSharedSizeScope="True">
    <Grid.ColumnDefinitions>
      <ColumnDefinition SharedSizeGroup="Index" Width="Auto"/>
      <ColumnDefinition/>
    </Grid.ColumnDefinitions>

    <Grid>
      <Rectangle Fill="{Binding Path=LineNumbersBackgroundColor, ElementName=LogViewerProperty}" Opacity="0.4" />
      <TextBlock Grid.Column="0" Margin="5,0,5,0" Style="{StaticResource MyLineNumberText}" x:Name="txtBoxLineNumbers" />
    </Grid>
    <TextBlock Grid.Column="1" Margin="5,0,0,0" Style="{StaticResource MyTextEditor}" />
  </Grid>
</DataTemplate>

<ListBox ItemsSource="{Binding}" x:Name="LogViewer" Background="{Binding Path=TextEditorBackgroundColor, ElementName=LogViewerProperty}" Style="{StaticResource MyListBox}" Foreground="{Binding Path=TextEditorForegroundColor, ElementName=LogViewerProperty}" ItemTemplateSelector="{StaticResource templateSelector}" Loaded="LogViewer_Loaded" SelectionMode="Extended" ItemContainerStyle="{StaticResource LeftAligned}" />

Is it possible when the left mouse button is pressed and the mouse is inside the TextBlock txtBoxLineNumbers to change the ItemContainerStyle in runtime? 当按下鼠标左键并且鼠标位于TextBlock txtBoxLineNumbers内部时,是否可以在运行时更改ItemContainerStyle?

All hints are welcome! 欢迎所有提示!

Update 更新资料

Ok, I found a solution: 好的,我找到了一个解决方案:

  var items = (sender as ListBox).SelectedItems;

  foreach (LogEntry item in items)
  {
    ListBoxItem myListBoxItem = (ListBoxItem) (LogViewer.ItemContainerGenerator.ContainerFromItem (item));
    ContentPresenter myContentPresenter = FindVisualChild<ContentPresenter> (myListBoxItem);
    DataTemplate myDataTemplate = myContentPresenter.ContentTemplateSelector.SelectTemplate (myListBoxItem, LogViewer);

    if (!mouseMove && leftMouseButtonDown)
    {
      TextBlock target = (TextBlock) myDataTemplate.FindName ("txtBoxLineNumbers", myContentPresenter);

      if (target.IsMouseOver && leftMouseButtonDown)
      {
        System.Windows.Resources.StreamResourceInfo info = Application.GetResourceStream (new Uri ("/LogViewer;component/Template/RightArrow.cur", UriKind.Relative));
        Cursor = new Cursor (info.Stream);
        fullSelectionBox = true;

        LogViewer.ItemContainerStyle = null;
        break;
      }

      LogViewer.ItemContainerStyle = (Style) FindResource ("LeftAligned");
    }

It seems to work! 看来行得通!

Instead of a textblock, you may use a button with control template set to a textblock as below: 您可以使用将控件模板设置为文本块的按钮来代替文本块,如下所示:

                            <Button MouseLeftButtonDown="Button_MouseLeftButtonDown_1">
                            <Button.Template>
                                <ControlTemplate>
                                    <TextBlock Grid.Column="0" Margin="5,0,5,0" Style="{StaticResource MyLineNumberText}" x:Name="txtBoxLineNumbers"/>
                                </ControlTemplate>
                            </Button.Template>
                        </Button>

Then in code behind, you will need: 然后在后面的代码中,您将需要:

 private void Button_MouseLeftButtonDown_1(object sender, MouseButtonEventArgs e)
        {
            var textblock = (sender as Button).Template.FindName("txtBoxLineNumbers", (sender as FrameworkElement)) as TextBlock;
            textblock.Text = "Hello World";
        }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM