2011-07-19 3 views
0

私はComboBoxの右側に十分なスペースがないところで、DropDownまたはPopupが右揃えのComboBoxを作成しようとしています。ComboBoxテンプレート内のポップアップ座標は?

FlowDirectionをRightToLeftに設定して右揃えにすることはできますが、右揃えにする必要があります。だから私はそれを使用してポップアップの右端を計算しようとしているX座標(RootVisualに相対)とそれの幅です。右端の値がRootVisualの幅より大きい場合、ComboBoxはPopupまたはDropDownの右揃えが必要です。

私の問題は、ポップアップがコンボボックスの座標を継承していることです。ポップアップの座標が正しくないのはなぜですか? PopupはComboBoxのテンプレートの中に含まれているからですか?ここに私のサンプルコードでは、コンボボックスの単純化されたテンプレートは、コントロールのコードが背後にある... ...

<Style TargetType="local:CustomComboBox"> 
    <Setter Property="Padding" Value="6,2,25,2"/> 
    <Setter Property="Background" Value="#FF1F3B53"/> 
    <Setter Property="HorizontalContentAlignment" Value="Left"/> 
    <Setter Property="BorderThickness" Value="1"/> 
    <Setter Property="TabNavigation" Value="Once"/> 
    <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/> 
    <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/> 
    <Setter Property="BorderBrush"> 
     <Setter.Value> 
      <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> 
       <GradientStop Color="#FFA3AEB9" Offset="0"/> 
       <GradientStop Color="#FF8399A9" Offset="0.375"/> 
       <GradientStop Color="#FF718597" Offset="0.375"/> 
       <GradientStop Color="#FF617584" Offset="1"/> 
      </LinearGradientBrush> 
     </Setter.Value> 
    </Setter> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="local:CustomComboBox"> 
       <Grid> 
        <Border x:Name="ContentPresenterBorder"> 
         <Grid> 
          <ToggleButton x:Name="DropDownToggle" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" HorizontalAlignment="Stretch" HorizontalContentAlignment="Right" Margin="0" Style="{StaticResource comboToggleStyle}" VerticalAlignment="Stretch"> 
           <Path x:Name="BtnArrow" Data="F1 M 301.14,-189.041L 311.57,-189.041L 306.355,-182.942L 301.14,-189.041 Z " HorizontalAlignment="Right" Height="4" Margin="0,0,6,0" Stretch="Uniform" Width="8"> 
            <Path.Fill> 
             <SolidColorBrush x:Name="BtnArrowColor" Color="#FF333333"/> 
            </Path.Fill> 
           </Path> 
          </ToggleButton> 
          <ContentPresenter x:Name="ContentPresenter" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"> 
           <TextBlock Text=" "/> 
          </ContentPresenter> 
         </Grid> 
        </Border> 
        <Popup x:Name="Popup"> 
         <Border x:Name="PopupBorder" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="3" HorizontalAlignment="Stretch" Height="Auto"> 
          <Border.Background> 
           <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> 
            <GradientStop Color="#FFFFFFFF" Offset="0"/> 
            <GradientStop Color="#FFFEFEFE" Offset="1"/> 
           </LinearGradientBrush> 
          </Border.Background> 
          <ScrollViewer x:Name="ScrollViewer" BorderThickness="0" Padding="1"> 
           <ItemsPresenter/> 
          </ScrollViewer> 
         </Border> 
        </Popup> 
       </Grid> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

です...コンボボックスのControlTemplateの中

public class CustomComboBox : ComboBox 
{ 
    private Popup _popup; 
    private ScrollViewer _scrollViewer; 

    public CustomComboBox() 
    { 
     this.DefaultStyleKey = typeof(CustomComboBox); 
    } 

    protected override void OnDropDownOpened(EventArgs e) 
    { 
     GeneralTransform gt = _popup.TransformToVisual(App.Current.RootVisual as UIElement); 
     Point popupOffset = gt.Transform(new Point(0, 0)); 

     double popupRightEdge = popupOffset.X + _popup.ActualWidth; 

     double appRightEdge = (App.Current.RootVisual as FrameworkElement).ActualWidth; 

     if (popupRightEdge > appRightEdge) 
     { 
      _popup.FlowDirection = FlowDirection.RightToLeft; 
      _scrollViewer.FlowDirection = FlowDirection.LeftToRight; 
     } 

     base.OnDropDownOpened(e); 
    } 

    public override void OnApplyTemplate() 
    { 
     base.OnApplyTemplate(); 

     _popup = GetTemplateChild("Popup") as Popup; 
     _scrollViewer = GetTemplateChild("ScrollViewer") as ScrollViewer; 
    } 
} 
+0

私はこれが答えに近づくと思います... "ポップアップは、テンプレートのルートオブジェクトの境界を基準にして開きます。" – Ewert

答えて

0

ValidationErrorElementはにポップアップを引き起こしました右実際のComboBoxの右端ではなく、自分自身に合わせます。私は、 "ポップアップ"であるポップアップコントロールの名前を、ComboBoxのControlTemplateの "DropDownPopup"のようなものに変更し、ポップアップのIsOpenプロパティをToggleButtonのIsCheckedプロパティにバインドすることをお勧めします。ポップアップはComboBoxのコントロールパートです。私はそれがそうするように動作するように、いくつかのコードがそれに接続されていると思われます。

また、私たちが使用した仮想化StackPanelはパフォーマンスを向上させましたが、他の奇妙な動作を作成しました。仮想化StackPanelで固定幅を設定すると固定されました。ポップアップで固定幅を設定すると、これも修正されます。

+0

このソリューションにコードを表示できますか? – SollyM

関連する問題