3

我正在使用 XAML 和 C# 开发 Windows 8 应用程序。我的 ComboBox 有问题,并有一个简单的示例来演示它。

  1. 将以下内容添加到布局感知页面(新 BasicPage)

    <ComboBox x:Name="comboBox1" DropDownClosed="comboBox1_DropDownClosed" Visibility="Collapsed" HorizontalAlignment="Left" Margin="179,217,0,0" Grid.Row="1" VerticalAlignment="Top" Width="998" Height="51">
        <x:String>Option 1</x:String>
        <x:String>Option 2</x:String>
        <x:String>Option 3</x:String>
    </ComboBox>
    <Button Click="Button_Click" Margin="585,130,0,416" Grid.Row="1" Height="82" Width="154">
        <Viewbox>
            <TextBlock Text="Press Me" />
        </Viewbox>
    </Button>
    
  2. 将此添加到页面的 CodeBehind

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        comboBox1.Visibility = Windows.UI.Xaml.Visibility.Visible;
        comboBox1.IsDropDownOpen = true;
    }
    
    private void comboBox1_DropDownClosed(object sender, object e)
    {
        comboBox1.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
    }
    

预期: 当按钮被按下时,ComboBox 应该出现并且选项应该展开,允许用户选择一个。一旦用户选择了一个选项,ComboBox 就会消失。

实际结果: 按下按钮时,没有任何反应。如果再次按下该按钮,ComboBox 会出现故障状态,并且应用程序基本上没有响应。(所有输入都指向 ComboBox,它永远不会关闭。

注意:DropDownClosed 事件在 Button_Click 事件之后立即触发。删除事件处理程序不会改变任何事情,但有趣的是 DropDownClosed 事件正在触发。

Rejected 解决方案: 建议我在更改生效后使用Dispatcher.RunAsync设置。这似乎是一种竞争条件,因为它只在某些时候有效。如果有办法确认 ComboBox 已呈现可见,则将此检查添加到 RunAsync 方法可以解决问题。IsDropDownOpenVisibility

作为一种解决方法,我目前将 Dispatcher.RunAsync 延迟 200 毫秒,这是一个烦人的解决方法。还有其他想法吗?

4

3 回答 3

1

多么讨厌的错误,啊?

一个简单的解决方法是不使用 Visibility 属性,而是使用 Opacity。它按预期工作:

   <ComboBox x:Name="comboBox1" DropDownClosed="comboBox1_DropDownClosed" Opacity="0" HorizontalAlignment="Left" Margin="179,217,0,0" Grid.Row="1" VerticalAlignment="Top" Width="998" Height="51">
        <x:String>Option 1</x:String>
        <x:String>Option 2</x:String>
        <x:String>Option 3</x:String>
    </ComboBox>


    private void Button_Click(object sender, RoutedEventArgs e) {
        comboBox1.Opacity = 1;
        comboBox1.IsDropDownOpen = true;
    }

    private void comboBox1_DropDownClosed(object sender, object e) {
        comboBox1.Opacity = 0;
    }

干杯!

于 2013-03-01T23:17:27.850 回答
1

你是对comboBox1的,在尝试设置IsDropDownOpen. 这样做的方法是通过以下方式拨打第二个电话Dispatcher

private void Button_Click(object sender, RoutedEventArgs e)
{
    comboBox1.Visibility = Windows.UI.Xaml.Visibility.Visible;
    Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => comboBox1.IsDropDownOpen = true);
}
于 2013-02-28T05:55:32.410 回答
0

我已经在我的台式机和 Surface 设备上测试了以下内容,它似乎一直都在工作。它是延迟设置的一种变体IsDropDownOpen。我了解您可能已经尝试了一些产生竞争条件的变体。我没有看到比赛条件,所以希望它也对你有用。

// need this for Task
using System.Threading.Tasks;
...

// note async keyword added to function signature
async private void Button_Click(object sender, RoutedEventArgs e)
{
    comboBox1.Visibility = Windows.UI.Xaml.Visibility.Visible;
    // add small delay before opening dropdown
    await Task.Delay(1);
    comboBox1.IsDropDownOpen = true;
}
于 2013-02-28T00:54:21.547 回答