Wpf “我的列表框”中的选定项目始终是上一个项目

Wpf “我的列表框”中的选定项目始终是上一个项目,wpf,Wpf,真的有一个问题,调试这个…原因可能很简单,但我仍然是一个业余的WPF 如果你看到代码会更容易,但我会告诉你具体的问题。我的listbox设置为包含网格格式,每个listboxitem都有一个listboxitem.PreviewMouseLeftButtonDown事件。问题是,所选项目始终设置为上一个项目 以下是分步骤进行的操作: 我的图像加载 我单击一个按钮,在图像上生成一个32x32单元格的网格覆盖,每个单元格在覆盖的单元格中都有一个listboxitem 我点击一个单元格 OnSelec

真的有一个问题,调试这个…原因可能很简单,但我仍然是一个业余的WPF

如果你看到代码会更容易,但我会告诉你具体的问题。我的listbox设置为包含网格格式,每个listboxitem都有一个listboxitem.PreviewMouseLeftButtonDown事件。问题是,所选项目始终设置为上一个项目

以下是分步骤进行的操作:

  • 我的图像加载

  • 我单击一个按钮,在图像上生成一个32x32单元格的网格覆盖,每个单元格在覆盖的单元格中都有一个listboxitem

  • 我点击一个单元格

  • OnSelected方法激发(每个listboxitem通过所选事件绑定到此处理程序)

  • 单击单元格(0,0)时,SelectedItem为空

  • 如果单击单元格(0,1),将触发选定事件,但现在SelectedItem将设置为上一个单元格(0,0)中的对象,而不是(0,1)。然后,单击(0,0)将显示SelectedItem为(0,1),依此类推

  • 对任何其他单元格重复此操作

  • XAML

     <DockPanel Name="dockTest">
            <Menu DockPanel.Dock="Top" Width="Auto" Height="Auto">
                <MenuItem Header="File">
                    <MenuItem Header="Load Image" Command="Open"></MenuItem>
                    <Separator />
                    <MenuItem Header="Exit" Command="Close"></MenuItem>
                </MenuItem>
            </Menu>
            <ListBox Name="lstTiles" DockPanel.Dock="Right" PreviewMouseRightButtonDown="grdMain_MouseRightButtonDown" 
                 PreviewMouseRightButtonUp="grdMain_MouseRightButtonUp"  SelectionMode="Extended">
                <ListBox.ItemContainerStyle>
                    <Style>
                    <EventSetter Event="ListBoxItem.Selected" Handler="OnSelected" />
                    <Setter Property="ListBox.RenderTransformOrigin" Value="0.5,0.5" />
                    <Setter Property="Grid.Row" Value="{Binding RelativeSource={x:Static RelativeSource.Self},
                        Path=Content.Row}"/>
                        <Setter Property="Grid.Column" Value="{Binding RelativeSource={x:Static RelativeSource.Self},
                        Path=Content.Column}"/>
                        <Setter Property="ListBoxItem.Height" Value="{Binding RelativeSource={x:Static RelativeSource.Self},
                        Path=Content.Height}" />
                        <Setter Property="ListBoxItem.Width" Value="{Binding RelativeSource={x:Static RelativeSource.Self},
                        Path=Content.Width}" />
                    <Setter Property="ListBoxItem.IsHitTestVisible" Value="True" />
                    <Style.Resources>
                            <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Blue" Opacity=".3" />
                            <SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="Transparent" />
                        </Style.Resources>
                    </Style>
                </ListBox.ItemContainerStyle>
                <ListBox.ItemsPanel>
                    <ItemsPanelTemplate>
                        <Grid ShowGridLines="True" IsItemsHost="True" Background="{DynamicResource LoadedImage}" 
                          Name="grdMain" MaxHeight="600" MaxWidth="800" MinHeight="600" MinWidth="800" >
                        </Grid>
                    </ItemsPanelTemplate>
                </ListBox.ItemsPanel>
            </ListBox>
        <StackPanel DockPanel.Dock="Left">
            <Label Margin="5">Tile Size</Label>
            <ComboBox Name="cmbGridSize">
                <TextBlock Name="txt3232">32x32</TextBlock>
                <TextBlock Name="txt1616">16x16</TextBlock>
                <TextBlock Name="txt88">8x8</TextBlock>
            </ComboBox>
            <Button Name="btnChangeGrid" Click="GridBtn_Click" Margin="4">Make Grid</Button>
            <Label>Tile Type</Label>
            <ComboBox Name="cmbTileType" SelectionChanged="cmbTileType_SelectionChanged">
    
            </ComboBox>
            <TextBlock Name="txtTest"></TextBlock>
            <Label>Tile Characteristic</Label>
            <ComboBox Name="cmbTileCharacteristic" SelectionChanged="cmbTileCharacteristic_SelectionChanged">
            </ComboBox>
            <Button Name="btnExport" Click="btnExport_Click">Export</Button>
            <Label>Edit Cell</Label>
            <Button Name="btnEdit" Click="btnEdit_Click">Edit Cell</Button>
        </StackPanel>
    </DockPanel>
    
    
    瓷砖尺寸
    32x32
    16x16
    8x8
    制作网格
    瓷砖类型
    瓷砖特性
    出口
    编辑单元
    编辑单元
    
    代码隐藏

        private void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            //Stores enum array of tile type enums
            tileTypes = Enum.GetNames(typeof(Tile.TileType));
    
            //Stores enum array of tile characteristics
            tileCharacteristics = Enum.GetNames(typeof(Tile.TileCharacteristic));
    
            //Gets main grid in template of main page
            mainGrid = Helpers.FindItemsPanel(lstTiles) as Grid;
    
            //Sets combobox to array of types of tiles
            cmbTileType.ItemsSource = tileTypes;
    
            //Sets combobox to array of characteristics
            cmbTileCharacteristic.ItemsSource = tileCharacteristics;
    
        }  //Generates the grid overlay
        private void Grid_Build()
        {
            //Sets grid overlay to user preferences of tile size
            if (tileList.Count > 0)
            {
                tileList.Clear();
            }
    
            if (mainGrid.RowDefinitions.Count > 0)
            {
                mainGrid.RowDefinitions.Clear();
            }
    
            if (mainGrid.ColumnDefinitions.Count > 0)
            {
                mainGrid.ColumnDefinitions.Clear();
            }
    
            int numberOfColumns = Convert.ToInt32(Math.Ceiling((float)imageWidth / (float)dimension));
            int numberOfRows = Convert.ToInt32(Math.Ceiling((float)imageHeight / (float)dimension));
    
            for (int i = 0; i < numberOfRows; i++)
            {
                mainGrid.RowDefinitions.Add(new RowDefinition());
            }
    
            for (int i = 0; i < numberOfColumns; i++)
            {
                mainGrid.ColumnDefinitions.Add(new ColumnDefinition());
            }
    
            int addCounter = 0;
    
            //Stores and generates tile objects in generated rows and columns
            for (int row = 0; row < numberOfRows; row++)
            {
                for (int col = 0; col < numberOfColumns; col++)
                {
                    Tile tempTile = (new Tile(row, col, dimension, dimension, addCounter, Tile.TileType.None, Tile.TileCharacteristic.Empty));
                    tempTile.IsHitTestVisible = true;
                    tileList.Add(tempTile);
                    addCounter++;
                }
            }
    
            //Sets listbox of tiles in xaml to the list of tile objects
            lstTiles.ItemsSource = tileList;
        }
    
        //Occurs when a listbox item is selected
        private void OnSelected(object sender, RoutedEventArgs e)
        {
            //If a single tile object is selected
            if (lstTiles.SelectedItems.Count == 1)
            {
                //Stores array of selected tile listboxitems in listbox
                var items = lstTiles.SelectedItems;
    
                foreach (Tile it in items)
                {
                    txtTest.Text = it.Row.ToString() + " " + it.Column.ToString();
    
                    //Sets tile type combobox to the property set in each tile object
                    cmbTileType.SelectedItem = (string)Enum.GetName(typeof(Tile.TileType), it.Type);
    
                    //Sets tile characteristic combobox to the property set in each tile object
                    cmbTileCharacteristic.SelectedItem = (string)Enum.GetName(typeof(Tile.TileCharacteristic), it.Characteristic);
                }
            }
        }
    
    private void主窗口\u已加载(对象发送方,路由目标)
    {
    //存储平铺类型枚举的枚举数组
    tileTypes=Enum.GetNames(typeof(Tile.TileType));
    //存储磁贴特征的枚举数组
    tileCharacteristics=Enum.GetNames(typeof(Tile.TileCharacteristic));
    //获取主页面模板中的主网格
    mainGrid=Helpers.FindItemsPanel(lstTiles)作为网格;
    //将组合框设置为平铺类型的数组
    cmbTileType.ItemsSource=tiletype;
    //将组合框设置为特征数组
    cmbTileCharacteristic.ItemsSource=tileCharacteristics;
    }//生成网格覆盖
    专用void Grid_Build()
    {
    //将栅格覆盖设置为平铺大小的用户首选项
    如果(tileList.Count>0)
    {
    tileList.Clear();
    }
    如果(mainGrid.RowDefinitions.Count>0)
    {
    mainGrid.RowDefinitions.Clear();
    }
    如果(mainGrid.ColumnDefinitions.Count>0)
    {
    mainGrid.ColumnDefinitions.Clear();
    }
    int numberOfColumns=Convert.ToInt32(数学上限((浮点)图像宽度/(浮点)尺寸));
    int numberOfRows=Convert.ToInt32(数学天花板((浮动)图像高度/(浮动)尺寸));
    for(int i=0;i
    这可能是因为您使用的是“鼠标按下预览”,所以在列表框接收到鼠标按下事件并将正确的项目设置为“选定”之前,鼠标按下事件就会触发。尝试切换到鼠标左键向下,看看这是否解决了问题。

    您的代码似乎与您的解释不符。您说,
    OnSelected
    方法是由于
    PreviewLeftMouseButtonDown
    而激发的,但您的XAML有:

    <EventSetter Event="ListBoxItem.Selected" Handler="OnSelected" />
    
    
    
    如果您的
    OnSelected
    方法是通过
    Preview
    事件调用的,那么您的问题就完全有意义了<代码>预览事件在控件处理它们之前引发,因此选择尚未生效。这使您有机会取消事件,从而使其永远不会“到达”控件

    因此,记住这一点,您可以理解为什么第一次选择时
    SelectedItem
    null