2016-11-01 9 views
0

トピックとして述べました。アプリケーションのすべてのボタンに1つのポップアップしか使用しません。私が望むものを手に入れる方法がわかりません。ここ は私の窓のように見えるものです:すべてのボタンの1つのポップアップ

enter image description here

情報1

enter image description here

情報2:

enter image description here

ポップアップが間違った位置に表示されるのを見ることができます.PlacementTargetを設定することでポップアップの位置を決めることができます。しかし、それぞれのポップアップは配置プロパティの値が異なります。これは問題です。ここで

はオプション1のポップアップです:オプション2のための

<StackPanel Orientation="Horizontal"> 
<!--Option 1: text and button--> 
<TextBlock Text="Option 1" 
    Margin="10" 
    VerticalAlignment="Center" /> 
<Popup x:Name="popInfo" 
    PlacementTarget="{Binding ElementName=btnInfoOption1}" 
    IsOpen="{Binding IsShowInfo1}"> 
    <ContentControl Style="{StaticResource ContentInfoStyle}"> 
    <TextBlock Text="{Binding InfoContent}" 
     TextWrapping="Wrap" 
     Foreground="White" 
     Width="340" 
     Padding="10" 
     Margin="30,0,30,5" 
     FontSize="15" /> 
    </ContentControl> 
</Popup> 

<Button x:Name="btnInfoOption1" 
    Style="{StaticResource btnIcons}" 
    Background="#0063b1" 
    Width="30" 
    Height="30" 
    Margin="10,10,20,10" 
    Command="{Binding CmdShowInfo, Delay=1500}" 
    Tag="{StaticResource ic_ginfo}" /> 
</StackPanel> 

はポップアップ:

<StackPanel Orientation="Horizontal"> 
<!--Option 2: text and button--> 
<TextBlock Text="Option 2" 
    Margin="10" 
    VerticalAlignment="Center" /> 
    <Button x:Name="btnOption2" 
    Style="{StaticResource btnIcons}" 
    Background="#0063b1" 
    Width="30" 
    Height="30" 
    Margin="10,10,20,10" 
    Command="{Binding CmdShowInfo, Delay=1500}" 
    Tag="{StaticResource ic_ginfo}" /> 
</StackPanel> 

ContentControlにスタイル:

<Style TargetType="{x:Type ContentControl}" 
x:Key="ContentInfoStyle"> 
<Setter Property="ContentTemplate"> 
    <Setter.Value> 
    <DataTemplate> 
    <Border Background="Green" 
     CornerRadius="3" 
     Padding="10,0,12,10"> 
    <StackPanel> 
     <Button HorizontalAlignment="Right" 
     Tag="{StaticResource ic_gclear}" 
     Style="{StaticResource btnIcons}" 
     Background="White" 
     Margin="10,5,12,5" 
     Command="{Binding DataContext.CmdCloseInfo}" 
     Height="24" /> 
     <ContentPresenter x:Name="content" 
      TextBlock.FontSize="14" 
      TextBlock.Foreground="White" 
      TextBlock.FontFamily="Arial" 
      Content="{TemplateBinding ContentControl.Content}" /> 
    </StackPanel> 
    </Border> 
    </DataTemplate> 
    </Setter.Value> 
    </Setter> 
</Style> 

ボタンのアイコンのスタイル:

<Style TargetType="Button" 
    x:Key="btnIcons">   
    <Setter Property="Template"> 
    <Setter.Value> 
    <ControlTemplate TargetType="{x:Type Button}"> 
     <Border x:Name="brd" Background="Transparent" 
     SnapsToDevicePixels="True"> 
     <VisualStateManager.VisualStateGroups> 
     <VisualStateGroup x:Name="CommonStates"> 
     <VisualState x:Name="Normal" /> 
     <VisualState x:Name="MouseOver" /> 
     <VisualState x:Name="Pressed" /> 
     </VisualStateGroup> 
     </VisualStateManager.VisualStateGroups> 
     <Path Stretch="Uniform" VerticalAlignment="Center" 
     Fill="{TemplateBinding Background}" 
     Data="{TemplateBinding Tag}" /> 
     </Border> 
    </ControlTemplate> 
    </Setter.Value> 
    </Setter> 
</Style> 

ViewModel.cs:ポップアップの 内容:

private string _InfoContent; 

public string InfoContent 
{ 
    get { return _InfoContent; } 
    set 
    { 
    if (value != _InfoContent) 
    { 
     _InfoContent = value; 
     OnRaise("InfoContent"); 
    } 
    } 
} 

オプション2オプション1のポップアップを表示:

private bool _IsShowInfo2; 

public bool IsShowInfo2 
{ 
    get { return _IsShowInfo2; } 
    set 
    { 
    if (value != _IsShowInfo2) 
    { 
     _IsShowInfo2 = value; 
     OnRaise("IsShowInfo2"); 
    } 
    } 
} 
//show the popup for option1 
private bool _IsShowInfo1; 

public bool IsShowInfo1 
{ 
    get { return _IsShowInfo1; } 
    set 
    { 
    if (value != _IsShowInfo1) 
    { 
     _IsShowInfo1 = value; 
     OnRaise("IsShowInfo1"); 
    } 
    } 
} 

コマンドボタンのために:

private ICommand _CmdShowInfo; 

public ICommand CmdShowInfo 
{ 
    get 
    { 
    _CmdShowInfo = _CmdShowInfo ?? new RelayCommand(x => this.ShowInfo(true, 1),() => true); 
    return _CmdShowInfo; 
    } 
} 

private ICommand _CmdShowInfo2; 

public ICommand CmdShowInfo2 
{ 
    get 
    { 
    _CmdShowInfo2 = _CmdShowInfo2 ?? new RelayCommand(x => this.ShowInfo(true, 0),() => true); 
    return _CmdShowInfo2; 
    } 
} 

private void ShowInfo(bool show = true, byte option = 0) 
{ 
    if (option == 0) 
    { 
    this.InfoContent = "Option 1..."; 
    } 
    else if (option == 1) 
    { 
    this.InfoContent = "Option 2..."; 
    } 
    this.IsShowInfo1 = show; 
} 
+0

"オプション2のポップアップ"はポップアップではありません。あなたが求めていることを確かめるのは難しいですが、あなたが望むのは 'Popup'要素を1つしか持たず、別のコンテンツを表示するだけでよい場合は、' HeaderContext'スタイルを 'ContentTemplate'で' Header'ボタン内のコンテンツで、 'Popup'中の' Content'です。 –

+0

はい、難しいことは分かります。HeaderedContentControl対ポップアップの詳細を教えてください。@EdPlunkett – Jandy

+0

ic_gclearとic_ginfoの定義を見ることはできますか? –

答えて

1

私の最初の考えは、スタイルHeaderedContentControlでこれを行うことでしたが、アイコンの塗りつぶしの色とアイコンのデータがあり、それらのプロパティを追加する必要がありました。一度そこに行けば、カスタムコントロールを書くこともできます。 IconPopupButton

の依存関係プロパティは、任意の依存関係プロパティのようにバインドすることができます。

<hec:IconPopupButton 
    IsOpen="{Binding IsShowInfo1}" 
    IconFill="YellowGreen" 
    Content="Another Test Popup" 
    IconData="M -10,-10 M 0,3 L 17,20 L 20,17 L 3,0 Z M 0,0 L 0,20 L 20,20 L 20,0 Z" 
    /> 

あなたはStyleは、別の依存関係プロパティを追加し、PopupContentControlに適用されるパラメータ化したい場合。あなたはテンプレートの親の上でIsOpenにバインドされることが必要なので、いくつかの考えを与える必要があります。おそらく、それをポップアップボタンのIsOpenにバインドされているviewmodelプロパティにバインドすることができます。常に方法があります。

だからここです。依存関係のプロパティを作成するためのスニペットを使用すると、これは空白を埋めるだけのことです。目に会うよりもはるかに少ないです。

<Window 
    x:Class="HeaderedPopupTest.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:local="clr-namespace:HeaderedPopupTest" 
    xmlns:hec="clr-namespace:HollowEarth.Controls" 
    mc:Ignorable="d" 
    Title="MainWindow" Height="350" Width="525" 
    > 
    <Window.Resources> 
     <ResourceDictionary> 
      <ResourceDictionary.MergedDictionaries> 
       <ResourceDictionary Source="Themes\Shared.xaml" /> 
      </ResourceDictionary.MergedDictionaries> 

      <Style 
       x:Key="InfoPopupButton" 
       TargetType="hec:IconPopupButton" 
       BasedOn="{StaticResource {x:Type hec:IconPopupButton}}" 
       > 
       <Setter Property="IconFill" Value="DeepSkyBlue" /> 
       <Setter Property="IconData" Value="{StaticResource ic_ginfo}" /> 
      </Style> 
     </ResourceDictionary> 
    </Window.Resources> 

    <Grid> 
     <StackPanel 
      Orientation="Vertical" 
      HorizontalAlignment="Left" 
      > 
      <hec:IconPopupButton 
       Style="{StaticResource InfoPopupButton}" 
       Content="This is a test popup" 
       ToolTip="Test Popup Tooltip" 
       /> 
      <hec:IconPopupButton 
       IconFill="YellowGreen" 
       Content="Another Test Popup" 
       IconData="M -10,-10 M 0,3 L 17,20 L 20,17 L 3,0 Z M 0,0 L 0,20 L 20,20 L 20,0 Z" 
       /> 
      <hec:IconPopupButton 
       IconFill="DarkRed" 
       Content="Missing IconData behavior example" 
       /> 
     </StackPanel> 
    </Grid> 
</Window> 

<ResourceDictionary 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="clr-namespace:HeaderedPopupTest.Themes" 
    > 
    <Geometry x:Key="ic_gclear">M56,4 52,0 28,24 4,0 0,4 24,28 0,52 4,56 28,32 52,56 56,52 32,28Z</Geometry> 
    <Geometry x:Key="ic_ginfo">M31,0C13.879,0,0,13.879,0,31s13.879,31,31,31s31-13.879,31-31S48.121,0,31,0z M34,46h-6V27.969h6V46z M34,21.969h-6V16h6V21.969z</Geometry> 

    <Style TargetType="ButtonBase" x:Key="btnIcons"> 
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate TargetType="{x:Type ButtonBase}"> 
        <Border x:Name="brd" Background="Transparent" SnapsToDevicePixels="True"> 
         <VisualStateManager.VisualStateGroups> 
          <VisualStateGroup x:Name="CommonStates"> 
           <VisualState x:Name="Normal" /> 
           <VisualState x:Name="MouseOver" /> 
           <VisualState x:Name="Pressed" /> 
          </VisualStateGroup> 
         </VisualStateManager.VisualStateGroups> 
         <Grid> 
          <Path 
           x:Name="Path" 
           Stretch="Uniform" 
           VerticalAlignment="Center" 
           Fill="{TemplateBinding Background}" 
           Data="{TemplateBinding Tag}" 
           /> 
          <TextBlock 
           x:Name="MissingIconData" 
           Visibility="Collapsed" 
           Text="?" 
           FontWeight="Bold" 
           FontSize="30" 
           ToolTip="IconData (Tag) not set" 
           HorizontalAlignment="Center" 
           VerticalAlignment="Center" 
           /> 
         </Grid> 
        </Border> 
        <ControlTemplate.Triggers> 
         <Trigger Property="Tag" Value="{x:Null}"> 
          <Setter TargetName="MissingIconData" Property="Visibility" Value="Visible" /> 
         </Trigger> 
        </ControlTemplate.Triggers> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 

</ResourceDictionary> 

テーマ

<ResourceDictionary 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="clr-namespace:HeaderedPopupTest.Themes" 
    xmlns:hec="clr-namespace:HollowEarth.Controls" 
    > 

    <ResourceDictionary.MergedDictionaries> 
     <!-- Change HeaderedPopupTest to the name of your own assembly --> 
     <ResourceDictionary Source="/HeaderedPopupTest;component/Themes/Shared.xaml" /> 
    </ResourceDictionary.MergedDictionaries> 

    <Style TargetType="hec:IconPopupButton"> 
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate TargetType="hec:IconPopupButton"> 
        <Grid x:Name="Grid"> 
         <ToggleButton 
          x:Name="OpenButton" 
          Style="{StaticResource btnIcons}" 
          Background="{TemplateBinding IconFill}" 
          Tag="{TemplateBinding IconData}" 
          IsChecked="{Binding IsOpen, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}" 
          ToolTip="{TemplateBinding ToolTip}" 
          /> 
         <Popup 
          x:Name="Popup" 
          StaysOpen="{Binding StaysOpen, RelativeSource={RelativeSource TemplatedParent}}" 
          IsOpen="{Binding IsOpen, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}" 
          PlacementTarget="{Binding ElementName=ToggleButton}" 
          Placement="{TemplateBinding Placement}" 
          > 
          <Border 
           Background="Green" 
           CornerRadius="3" 
           Padding="10,0,12,10"> 
           <StackPanel> 
            <ToggleButton 
             HorizontalAlignment="Right" 
             Tag="{StaticResource ic_gclear}" 
             Style="{StaticResource btnIcons}" 
             Background="White" 
             Margin="10,5,12,5" 
             IsChecked="{Binding IsOpen, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}" 
             Height="24" 
             /> 
            <ContentPresenter 
             x:Name="content" 
             TextBlock.FontSize="14" 
             TextBlock.Foreground="White" 
             TextBlock.FontFamily="Arial" 
             Content="{TemplateBinding Content}" 
             /> 
           </StackPanel> 
          </Border> 
         </Popup> 
        </Grid> 
        <ControlTemplate.Triggers> 
         <MultiTrigger> 
          <MultiTrigger.Conditions> 
           <!-- 
           I don't understand this: If I use the templated parent's IsOpen, 
           the effect is as if it were never true. 
           --> 
           <Condition SourceName="Popup" Property="IsOpen" Value="True" /> 
           <Condition Property="StaysOpen" Value="False" /> 
          </MultiTrigger.Conditions> 
          <!-- 
          If StaysOpen is false and the button is enabled while the popup is open, 
          then clicking on it will cause the popup to flicker rather than close. 
          --> 
          <Setter TargetName="OpenButton" Property="IsEnabled" Value="False" /> 
         </MultiTrigger> 
        </ControlTemplate.Triggers> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 
</ResourceDictionary> 

MainWindow.xamlの使用例Generic.xaml \ Shared.xaml \

IconPopupButton.cs

using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Controls.Primitives; 
using System.Windows.Media; 

namespace HollowEarth.Controls 
{ 
    public class IconPopupButton : ContentControl 
    { 
     static IconPopupButton() 
     { 
      DefaultStyleKeyProperty.OverrideMetadata(typeof(IconPopupButton), new FrameworkPropertyMetadata(typeof(IconPopupButton))); 
     } 

     #region IconData Property 
     public Geometry IconData 
     { 
      get { return (Geometry)GetValue(IconDataProperty); } 
      set { SetValue(IconDataProperty, value); } 
     } 

     public static readonly DependencyProperty IconDataProperty = 
      DependencyProperty.Register("IconData", typeof(Geometry), typeof(IconPopupButton), 
       new PropertyMetadata(null)); 
     #endregion IconData Property 

     #region IconFill Property 
     public Brush IconFill 
     { 
      get { return (Brush)GetValue(IconFillProperty); } 
      set { SetValue(IconFillProperty, value); } 
     } 

     public static readonly DependencyProperty IconFillProperty = 
      DependencyProperty.Register("IconFill", typeof(Brush), typeof(IconPopupButton), 
       new PropertyMetadata(SystemColors.ControlTextBrush)); 
     #endregion IconFill Property 

     #region IsOpen Property 
     public bool IsOpen 
     { 
      get { return (bool)GetValue(IsOpenProperty); } 
      set { SetValue(IsOpenProperty, value); } 
     } 

     public static readonly DependencyProperty IsOpenProperty = 
      DependencyProperty.Register("IsOpen", typeof(bool), typeof(IconPopupButton), 
       new PropertyMetadata(false)); 
     #endregion IsOpen Property 

     #region StaysOpen Property 
     public bool StaysOpen 
     { 
      get { return (bool)GetValue(StaysOpenProperty); } 
      set { SetValue(StaysOpenProperty, value); } 
     } 

     public static readonly DependencyProperty StaysOpenProperty = 
      DependencyProperty.Register("StaysOpen", typeof(bool), typeof(IconPopupButton), 
       new PropertyMetadata(false)); 
     #endregion StaysOpen Property 

     #region Placement Property 
     public PlacementMode Placement 
     { 
      get { return (PlacementMode)GetValue(PlacementProperty); } 
      set { SetValue(PlacementProperty, value); } 
     } 

     public static readonly DependencyProperty PlacementProperty = 
      DependencyProperty.Register("Placement", typeof(PlacementMode), typeof(IconPopupButton), 
       new PropertyMetadata(PlacementMode.Right)); 
     #endregion Placement Property 
    } 
} 

テーマ10

ボタンをToggleButtonに変更したことがわかります。これは便宜上、IsOpenプロパティまで配線しています。ToggleButtonでは、IsCheckedをバインドするだけです。コマンドの必要はありません。 StaysOpenfalseである場合、ユーザーがPopupの開いているボタンをクリックすると、フォーカス変更によってPopupが閉じられ、ボタンのチェックを外し、、次にボタンがマウスメッセージを取得します。ボタンがポップアップを再び開きます。これはユーザの視点から見ると奇妙な動作なので、ポップアップが開いていてStaysOpenがfalseのときにボタンを無効にするトリガを追加します。 StaysOpenがtrueの場合、フォーカスを変更してもPopupが閉じないので、その場合はボタンを有効にします。

のスタイルをButtonBaseに変更したので、ButtonToggleButtonと同じように動作します。

+0

私はそれが何ではない。カスタムコントロールのようだ.ToggleButtonとTextBox Collapsed.lol。 – Jandy

+0

@Jandy私があなたに何を教えようとしているのか分かりません。 –

+0

ウィンドウが非アクティブになると消えます。コマンドは必要ありません。ポップアップを表示してください。素晴らしいです!私はscrollviewerに配置しようとします。私はそれがより多くのメモリを必要としないことを願っています。@EdPlunkett – Jandy

関連する問題