Динамически установить позицию всплывающего окна / размещение - PullRequest
3 голосов
/ 02 марта 2010

Элемент управления Popup по умолчанию выровнен по левому краю. Его левый край выровнен с левым краем его родителя.

Я хотел бы выровнять элемент управления по правому краю, чтобы его правый край был выровнен по правому краю контейнера.

Я хочу, чтобы это было динамическим, потому что я динамически связываю данные и не знаю, насколько большим будет всплывающее окно.

Я пытался играть с событиями Opened, SizeChanged и Loaded, чтобы получить ширину Child и установить ее на HorizontalOffset, но, похоже, есть проблемы с синхронизацией. Как правило, он работает нормально при первой загрузке элемента управления, а затем никогда после этого (HorizontalOffset установлен на 0).

Это ошибка? Я делаю это неправильно?

РЕДАКТИРОВАТЬ Я получил это работает. Кажется, что есть проблемы со временем. Если я подключу событие Opened и установлю HorizontalOffset асинхронно, используя Dispatcher, то это сработает: (

</p> <pre><code> private static void OnPopupOpened(object sender, System.EventArgs e) { var popup = (Popup)sender; popup.Dispatcher.BeginInvoke(() => popup.HorizontalOffset = -popup.ActualWidth); }

РЕДАКТИРОВАТЬ 2 Теперь я понимаю, что делал что-то глупое. Я хотел, чтобы Popup из ComboBox был выровнен по правому краю. Я не видел, чтобы он был повторно инициализирован в частном вызове метода ArrangePopup.
Я попытался унаследовать от ComboBox, чтобы переопределить функцию размещения, но я, должно быть, делал что-то не так, потому что она все еще не работает, хотя я переопределил методы, которые вызывают ArrangePopup

Приветствие.

Ответы [ 2 ]

3 голосов
/ 02 марта 2010

Теперь я понимаю, что если я не отвечу на свой вопрос, никто не сможет пометить мой обход как ответ. Итак, вот полный код. Я реализовал это как ПРИЗМУ.

public static class PopupRightAlignBehavior
{
    public static readonly DependencyProperty InstanceProperty =
        DependencyProperty.RegisterAttached("Instance", typeof(object), typeof(PopupRightAlignBehavior), new PropertyMetadata(OnSetInstanceCallback));

    public static object GetInstance(DependencyObject obj)
    {
        return (object)obj.GetValue(InstanceProperty);
    }

    public static void SetInstance(DependencyObject obj, object value)
    {
        obj.SetValue(InstanceProperty, value);
    }

    private static void OnSetInstanceCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var popup = (Popup)d;
        popup.Opened -= OnPopupOpened;
        popup.Opened += OnPopupOpened;
    }

    private static void OnPopupOpened(object sender, System.EventArgs e)
    {
        var popup = (Popup)sender;
        popup.Dispatcher.BeginInvoke(() => popup.HorizontalOffset = -popup.ActualWidth);
    }
}
0 голосов
/ 13 июля 2011

Что вы можете сделать, это использовать MS Expression Blend для создания шаблона по умолчанию для ComboBox. В шаблоне вы найдете всплывающее окно с именем Popup, измените его атрибут FlowDirection на RightToLeft ...

<Popup x:Name="Popup" FlowDirection="RightToLeft">

Обратите внимание, что объект ScrollViewer внутри Popup будет наследовать набор FlowDirection, поэтому вы должны явно установить его FlowDirection в LeftToRight ...

<ScrollViewer x:Name="ScrollViewer" BorderThickness="0" Padding="1" FlowDirection="LeftToRight">

... иначе он будет заполнен из RightToLeft, а полоса прокрутки будет на левой стороне.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...