3

XAML と C# を使用して Windows 8 アプリを開発しています。ComboBox に問題があり、それを示す簡単な例があります。

  1. 以下をレイアウト対応ページ (New 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 イベントが発生しています。

拒否された解決策:変更が有効になった後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。それを行う方法は、次の方法で 2 番目の呼び出しを行うことです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 に答える