4

ToggleButtonを開くためのがあり、既知のすべての要素などPopupと同じ動作をするとします。ComboBox

...これはこのコードです:

<ToggleButton x:Name="PART_OpenToggleButton"
    Focusable="False"   
    IsChecked="False"
    Template="{StaticResource MyToggleButton}"> 
    <Grid>                                           
        <Popup x:Name="PART_PopupControl"
               Style="{StaticResource MyPopupStyle}"
               StaysOpen="False"
               VerticalAlignment="Bottom"
               IsOpen="False"
               PlacementTarget="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ToggleButton, AncestorLevel=1}}" />
    </Grid>
</ToggleButton>

次に、コード ビハインドで . IsOpenPopup. IsCheckedのためにToggleButton。すべてが機能しますが、 を開いPopupて境界線の外側をクリックすると問題が発生します。はPopup閉鎖されますが、ToggleButton チェックされたままです。

をクリックしてを閉じると、 はそれ自体を閉じて設定しますが、同時に をクリックすると、を再度開こうとするPopupOnClosedため、ハンドラで を設定することはできません。したがって、閉じることはできません。ToggleButton.IsChecked = falseToggleButtonPopupPopupToggleButton.IsChecked = falseToggleButtonPopup

最初のトグルボタンクリック:

-> ToggleButton IsChecked = true

2 番目のトグル ボタン クリック:

-> ToggleButton IsChecked = false
-> ToggleButton IsChecked = true

そのため、ポップアップが開いているときにトグル ボタンをクリックすると、ポップアップは点滅しますが、開いたままになります。

この問題をどのように解決しますか?

編集:

これを MyWindow.XAML で試して、コード ビハインドに依存関係プロパティ IsDropDownOpen を追加してください。

<Grid>
        <ToggleButton x:Name="PART_OpenToggleButton"
                      Focusable="False"                          
                      Height="20"
                      Width="50"
                      IsChecked="{Binding ElementName=TestWindow, Mode=TwoWay, Path=IsDropDownOpen}">
            <Grid>

                <Popup x:Name="PART_PopupControl"
                       Width="100"
                       Height="100"
                       StaysOpen="False"
                       Focusable="False"
                       VerticalAlignment="Bottom"
                       IsOpen="{Binding ElementName=TestWindow, Path=IsDropDownOpen}"
                       PlacementTarget="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ToggleButton, AncestorLevel=1}}">                  
                </Popup>
            </Grid>
        </ToggleButton>
    </Grid>

public bool IsDropDownOpen
        {
            get { return (bool)GetValue(IsDropDownOpenProperty); }
            set { SetValue(IsDropDownOpenProperty, value); }
        }        
        public static readonly DependencyProperty IsDropDownOpenProperty =
            DependencyProperty.Register("IsDropDownOpen", typeof(bool), typeof(Window), new UIPropertyMetadata(false));
4

6 に答える 6

4

この投稿で解決策を見つけました: https://stackoverflow.com/a/5821819/651161

次のクラスを使用すると、トグルボタンが押される前にクリックを処理できます。ポップアップはクリックのために閉じられますが、クリックはその後処理されるため、ToggleButton クリックはトリガーされません。

public class MyPopup : Popup {
    protected override void OnPreviewMouseLeftButtonDown(MouseButtonEventArgs e) {
        bool isOpen = this.IsOpen;
        base.OnPreviewMouseLeftButtonDown(e);

        if (isOpen && !this.IsOpen)
            e.Handled = true;
    }
}
于 2013-08-06T07:28:49.700 に答える
3

わかりました、ここに私のために働くいくつかのコードがあります(それらは、いくつかの重要でない部分が削除された作業コードからコピーアンドペーストされています):

ComboBox のような UserControl の内容は次のとおりです。

<ToggleButton x:Name="Button" Height="19"> 
   <Grid>
        <Label Name="DisplayList" Content="Whatever" />
        <Popup Name="SelectionPopup" MinHeight="100" MinWidth="200"
                    StaysOpen="False" IsOpen="{Binding IsChecked, ElementName=Button}">
        </Popup>
     </Grid>
</ToggleButton>

カスタム テンプレートから実際の ComboBox まで:

<ToggleButton
      Name="ToggleButton"
      Template="{StaticResource ComboBoxToggleButton}"
      Grid.Column="2"
      Focusable="false"
      IsChecked="{Binding Path=IsDropDownOpen,Mode=TwoWay,RelativeSource={RelativeSource TemplatedParent}}"
      ClickMode="Press">
 </ToggleButton>
 <Popup
      Name="Popup"
      Placement="Bottom"
      IsOpen="{TemplateBinding IsDropDownOpen}"
      AllowsTransparency="True"
      Focusable="False"
      PopupAnimation="Slide">
于 2010-03-02T08:21:56.827 に答える
1

2 つの問題があるように思えます。1 つは、ポップアップ内のクリックが、ビジュアル ツリー内の位置に応じて再度処理される可能性があるという問題に対処することです。

2 つ目の問題は、クリックによる自動クローズです。ポップアップの外側をクリックするたびに実際に発生し、追加のイベントをトリガーする可能性があります。「開くボタン」をクリックしても閉じます。問題は、popup.isOpen で以前に設定された値がわからないことです。これは、開くボタンのクリック イベントハンドラーに対して常に false であるためです。

メモリを節約するためにトグルボタンを使用していませんが、重要な問題は同じだと思います。トグル ボタンは、クリックした瞬間にすでに false になっています。

私の例のポップアップは次のように定義されています。

<Popup Placement="Bottom" PopupAnimation="Slide" Name="PART_Popup" VerticalOffset="3" AllowsTransparency="True" StaysOpen="False">

プレースメント ターゲット (「開くボタン」) をクリックすると、ポップアップが閉じ、同時にボタンのクリック イベントが処理されましたが、popup.IsOpen プロパティは既に「false」であったため、再び開かれました。

これを解決するために私がしたことは、ポップアップの「Closed」イベントをサブスクライブして、時間を節約し、再オープンを1秒間ブロックすることでした。

DateTime? LastClose = new DateTime?();

private void Popup_Closed(object sender, EventArgs e)
{    LastClose = DateTime.Now;    }

public bool AllowReopen
{
    get {
            if ((popup == null) || (popup.IsOpen)) return false; 
            //You cannot open, when the template isn't applied or it is already open

            return !LastClose.HasValue || (DateTime.Now - LastClose.Value) > new TimeSpan(0,0,1) /*1s*/;
        }
}


public void OpenPopup()
{
     if (!AllowReopen) return;

     popup.IsOpen = true;
}
于 2016-09-05T11:53:23.043 に答える
1

PopupsStaysOpenプロパティを ButtonsIsMouseOverプロパティにバインドするだけです。IsMouseOver = false = StaysOpenこのようにすると、ポップアップ ( )以外の何かをクリックするとポップアップが閉じ、 ToggleButton( IsMouseOver = true = StaysOpen) をクリックするとポップアップが閉じます。このようにして、Popup 以外のクリックも処理されます。

<ToggleButton x:Name="Toggle" />
<Popup x:Name="Popup" IsOpen="{Binding ElementName=Toggle, Path=IsChecked, Mode=TwoWay}"
StaysOpen="{Binding ElementName=Toggle, Path=IsMouseOver}" />
于 2015-03-05T11:27:13.883 に答える
0

ViewModel の同じプロパティに両方の人をバインドします。Toolbox の既定のテンプレートで良い例を見つけることができます。

<ToggleButton x:Name="OverflowButton"
            FocusVisualStyle="{x:Null}"
            IsEnabled="{TemplateBinding HasOverflowItems}"
            Style="{StaticResource ToolBarHorizontalOverflowButtonStyle}"
            IsChecked="{Binding Path=IsOverflowOpen,Mode=TwoWay,RelativeSource={RelativeSource TemplatedParent}}"
            ClickMode="Press"/>
    <Popup x:Name="OverflowPopup"
         AllowsTransparency="true"
         Placement="Bottom"
         IsOpen="{Binding Path=IsOverflowOpen,RelativeSource={RelativeSource TemplatedParent}}"
         StaysOpen="false"
         Focusable="false"
         PopupAnimation="{DynamicResource {x:Static SystemParameters.ComboBoxPopupAnimationKey}}">
        <theme:SystemDropShadowChrome Name="Shdw" Color="Transparent">
            <Border Background="{StaticResource ToolBarSubMenuBackground}"
                    BorderBrush="{StaticResource ToolBarMenuBorder}"
                    BorderThickness="1">
                <ToolBarOverflowPanel x:Name="PART_ToolBarOverflowPanel"
                                    Margin="2"
                                    WrapWidth="200"
                                    Focusable="true"
                                    FocusVisualStyle="{x:Null}"
                                    KeyboardNavigation.TabNavigation="Cycle"
                                    KeyboardNavigation.DirectionalNavigation="Cycle"
                                    SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
            </Border>
        </theme:SystemDropShadowChrome>
    </Popup>

お役に立てれば、

乾杯、アンバカ。

于 2010-02-25T12:37:43.447 に答える
0

背景をクリックしてポップアップを閉じないようにするには、それを埋める何かを挿入します。

この例では、埋められていないスペースをクリックすると、ポップアップが閉じます。

<Popup x:Key="MyPop" Width="200" Height="200" StaysOpen="False">            
                <CheckBox Content="abc" />
</Popup>

この例では、埋められていないスペースをクリックしても、ポップアップは閉じません:

<Popup x:Key="MyPop" Width="200" Height="200" StaysOpen="False">
        <StackPanel Background="Red" Width="200" Height="200"> <!--EXTRA PANEL -->
                <CheckBox Content="abc" />
        </StackPanel>
</Popup>
于 2018-02-16T08:42:30.547 に答える