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