Выбранный элемент в моем списке всегда является предыдущим элементом - PullRequest
0 голосов
/ 04 октября 2010

У меня действительно есть проблема с отладкой ... причина, по-видимому, очень проста, но я все еще любитель WPF.

Будет проще, если вы увидите код, но я дам вам конкретныйпроблема.Мой список содержит формат сетки, и каждый элемент списка имеет событие ListBoxItem.PreviewMouseLeftButtonDown.Проблема в том, что для выбранного элемента всегда установлен предыдущий элемент.

Вот что происходит поэтапно:

  1. Мое изображение загружается

  2. Я нажимаю кнопку, чтобы создать наложение сетки размером 32x32 ячейки поверх изображения, каждый элемент списка в ячейке этого наложения

  3. Я нажимаю ячейку

  4. Срабатывает метод OnSelected (каждый элемент списка привязывается к этому обработчику через событие Selected)

  5. SelectedItem становится нулевым, когда я нажимаю на ячейку (0,0)

  6. Если я щелкну ячейку (0,1), событие Selected срабатывает, но теперь SelectedItem устанавливается для объекта в предыдущей ячейке (0,0) вместо (0,1).Затем нажатие (0,0) покажет SelectedItem как (0,1) и т. Д.

  7. Повторите для любой другой ячейки.

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>

Код сзади

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

Ответы [ 3 ]

1 голос
/ 04 октября 2010

Может случиться так, что, поскольку вы используете предварительную мышку вниз, событие нажатия мыши запускается до того, как список получит его и соответствующим образом установит правильный элемент для выбранного.Попробуйте вместо этого переключиться на левую кнопку мыши и посмотреть, решит ли это проблему.

0 голосов
/ 07 октября 2010

Выбранная проблема была преждевременным событием для получения контейнера selecteditems списка. То, что я должен был использовать, было SelectionChanged

0 голосов
/ 04 октября 2010

Ваш код не соответствует вашему объяснению. Вы говорите, что OnSelected метод срабатывает в результате PreviewLeftMouseButtonDown, но ваш XAML имеет:

<EventSetter Event="ListBoxItem.Selected" Handler="OnSelected" />

Если ваш OnSelected метод вызывается через событие Preview, ваша проблема имеет смысл. Preview события генерируются до того, как их обработает элемент управления, поэтому выбор еще не был принят. Это дает вам возможность отменить событие, чтобы оно никогда не «достигло» элемента управления.

Итак, помня об этом, вы можете понять, почему SelectedItem равен null при первом выборе элемента - у ListBox еще не было возможности применить выбор. И последующие выборы всегда будут одним шагом по той же причине.

Если ваш обработчик событий полагается на выбранные варианты, вам нужно убедиться, что они срабатывают после того, как ListBox сможет применить их. Событие ListBoxItem.Selected будет достаточно для этого. Вот почему я запутался в вашем коде.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...