【问题标题】:C# WPF: Fire SelectionChanged Event First Before others EventsC# WPF:在其他事件之前首先触发 SelectionChanged 事件
【发布时间】:2012-04-11 10:25:19
【问题描述】:

我的问题很简单:
我有一个包含一些DataTemplate 的列表框。 如您所见,我在列表框中有 SelectionChanged 事件:

SelectionChanged = "stationListBox_SelectionChanged"

以及网格内的 mouseDown 事件(网格是数据模板的一部分):

MouseDown = "Grid_MouseDown"

我希望SelectionChanged 事件首先被触发,然后是MouseDown 事件。 那是因为我想对选定的项目做点什么,所以我需要先知道我选择了谁。

XML:

<ListBox x:Name="stationListBox" Grid.Row="0" ItemsSource="{Binding}" SelectionChanged="stationListBox_SelectionChanged" Background="#FF5C7591"                             
    VerticalAlignment="Stretch" HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch">
    <ListBox.Resources>
        <DataTemplate DataType="{x:Type viewModels:StationViewModel}">
            <Grid Margin="0,0,0,2"  IsEnabled="{Binding IsEnabled, Mode=TwoWay}" MouseDown="Grid_MouseDown" >
            <Frame BorderBrush="#B935373F" BorderThickness="4"></Frame>
                <StackPanel Orientation="Vertical" Margin="10" >                
                    <StackPanel Orientation="Horizontal">
                        <Image Width="30" Height="30" Margin="3,0" Source="Images\station.png" HorizontalAlignment="Left" />
                        <TextBlock Text="{Binding Name}" FontSize="14" TextAlignment="Left" Width="80" FontFamily="Arial"/>
                            <Grid>
                                <Image Width="20" Height="20" Margin="3,0" Source="Images\turnOn.png" HorizontalAlignment="Right" Visibility="{Binding IsStationOpen, Mode=TwoWay}" />
                                <Image Width="20" Height="20" Margin="3,0" Source="Images\turnOff.png" HorizontalAlignment="Right" Visibility="{Binding IsStationClose, Mode=TwoWay}" />
                               </Grid>
                        <Image Width="20" Height="20" Margin="3,0" Source="Images\delete2.png" HorizontalAlignment="Right" Visibility="{Binding Mode=TwoWay, Path=IsSelected}"
                            ToolTip="Delete station" MouseDown="Image_MouseDown" />
                    </StackPanel>                
                    <StackPanel Name="_editStationGrid" Orientation="Vertical" Visibility="{Binding IsEditable,Mode=TwoWay}">
                        <Expander Visibility="Visible" IsExpanded="{Binding IsExpandered, Mode=TwoWay}">
                            <Expander.Header>
                                <StackPanel Orientation="Horizontal">
                                    <TextBlock>Edit Station:</TextBlock>
                                </StackPanel>
                            </Expander.Header>
                            <StackPanel Orientation="Vertical">
                                <StackPanel Orientation="Horizontal" Margin="20,5,5,5" >
                                    <Label Content="Name:"/>
                                    <TextBox MinWidth="120" Text="{Binding Name, Mode=TwoWay}"></TextBox>
                                </StackPanel>
                                <StackPanel Orientation="Horizontal" Margin="20,0,5,0" >
                                    <Label Content="IP:" Margin="0,0,20,0"/>
                                    <TextBox MinWidth="120" Text="{Binding IP, Mode=TwoWay}" ></TextBox>
                                </StackPanel>
                            </StackPanel>
                        </Expander>
                    </StackPanel>
                </StackPanel>
            </Grid>
        </DataTemplate>
    </ListBox.Resources>
</ListBox>

代码:

private void stationListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    this._selectedStation = ((StationViewModel)this.stationListBox.SelectedItem);
}

private void Grid_MouseDown(object sender, MouseButtonEventArgs e)
{
    if (inEditMode && e.ClickCount == 1)
    {
        if (_selectedStation.IsSelected == System.Windows.Visibility.Visible)
            _selectedStation.IsSelected = System.Windows.Visibility.Collapsed;
        else
            _selectedStation.IsSelected = System.Windows.Visibility.Visible;
    }

    if (!inEditMode && e.ClickCount == 2)
    {
        if (_selectedStation_Event != null)
            _selectedStation_Event(_selectedStation);
    }
}

【问题讨论】:

  • 为什么不在 SelectionChanged 事件处理程序中做那件事?
  • 因为我需要观察是否有单击项目或双击,为此我需要 mouseEventArgs 对象(e.Clicks 属性)。我需要首先选择将发生变化,而不是在 mouseDown 事件触发之后。

标签: c# wpf events listbox listboxitem


【解决方案1】:

您可以使用 Dispatcher 对象:

    private void Grid_MouseDown(object sender, MouseButtonEventArgs e)
    {
        this.Dispatcher.BeginInvoke(new Action(delegate
        {
            // do stuff
        }
        ));
    }

【讨论】:

  • 这对我没有帮助,因为我需要先知道谁选择了该项目,然后对该项目进行操作。
  • 你试过了吗?使用调度程序将使用事件队列来推迟相应处理程序的处理。 SelectedChanged 事件将首先发生。见link
  • 嗨,你给我的解决方案部分帮助了我,因为当它进入 mouseDown 方法和 BeginInvoke 时,而不是在进入 SelectionChange 方法之后,但在此之后,它又回到 selctionChange 方法并在这次选中的项,为空;
猜你喜欢
  • 1970-01-01
  • 2021-03-17
  • 2014-05-02
  • 1970-01-01
  • 2012-06-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-15
相关资源
最近更新 更多