Silverlight RadComboBox делает всю область texbox доступной для кликов

Можно ли сделать всю текстовую область RadComboBox доступной для кликов, если IsEditable=true и ReadOnly=True?

Я бы просто установил IsEditable = false, но, к сожалению, мне нужно, чтобы его можно было редактировать, чтобы отображать пользовательский текст, когда что-то выбрано (я установил его, чтобы можно было выбрать несколько вещей и представить список выбранных элементов). Если я отключу IsEditable, я потеряю атрибут .Text и не смогу установить собственный текст.

Мои два лучших варианта:
1) каким-то образом применить стиль, который сделает кликабельной всю текстовую панель, а не только стрелку
2) каким-то образом применить настраиваемый текстовый дисплей, когда для параметра IsEditable установлено значение false.

К сожалению, я не знаю, как это сделать, поэтому любая помощь будет приятной. Спасибо

Изменить: это было бы идеально, за исключением того, что мы используем Silverlight, а не ASP.net http://demos.telerik.com/aspnet-ajax/combobox/examples/functionality/checkboxes/defaultcs.aspx

Это, вероятно, более реалистично, просто чтобы как-то сделайте текстовую область кликабельной, чтобы она открывала выпадающее меню. Точно так же, как ComboBox справа, за исключением возможности печатать.
http://demos.telerik.com/aspnet-ajax/combobox/examples/functionality/comboboxvsdropdownlist/defaultcs.aspx


person Max    schedule 06.10.2014    source источник


Ответы (2)


Я могу придумать несколько решений разной элегантности. Вот тот, который может подойти, чтобы закрыть оставшийся разрыв между Arrow-ToggleButton и Text-Input-Area. И теперь, когда я думаю об этом... может быть, вы сможете избавиться от этого довольно вонючего и хрупкого побочного эффекта со свойством OpenDropDownOnFocus (которое сломается, как только щелчок не изменит владельца фокуса).

Зарегистрируйте обработчик кликов MouseLeftButtonDown в RadComboBox, вы можете получать все события, а не только необработанные события. Затем мы можем переключить DropDown оттуда. Но мы не хотим мешать Arrow-ToggleButton, поэтому проверяем, откуда произошел щелчок мыши.

public class MyView : UserControl
{
    public MyView()
    {
        InitializeComponent();
        MouseButtonEventHandler handler = OnComboBoxClicked;
        radComboBox.AddHandler( UIElement.MouseLeftButtonDownEvent, handler,
            handledEventsToo: true );
    }

    private void OnComboBoxClicked( object sender, MouseButtonEventArgs args )
    {
        if (!args.Handled ||
            !args.IsRoutedEventFromToggleButton(
                togglebuttonAncestorToStopTheSearch: (UIElement) sender))
        {
            ToggleDropDown();
        }
    }
}

и методы расширения для более удобного использования:

public static class ControlExtensions
{
    public static bool IsRoutedEventFromToggleButton(
        this RoutedEventArgs args,
        UIElement togglebuttonAncestorToStopTheSearch )
    {
        ToggleButton toggleButton = ((UIElement) args.OriginalSource)
            .GetAncestor<ToggleButton>( togglebuttonAncestorToStopTheSearch );
        return toggleButton != null;
    }

    public static TAncestor GetAncestor<TAncestor>(
        this DependencyObject subElement,
        UIElement potentialAncestorToStopTheSearch )
        where TAncestor : DependencyObject
    {
        DependencyObject parent;
        for (DependencyObject subControl = subElement; subControl != null;
             subControl = parent)
        {
            if (subControl is TAncestor) return (TAncestor) subControl;

            if (object.ReferenceEquals( subControl,
                potentialAncestorToStopTheSearch )) return null;


            parent = VisualTreeHelper.GetParent( subControl );
            if (parent == null)
            {
                FrameworkElement element = subControl as FrameworkElement;
                if (element != null)
                {
                    parent = element.Parent;
                }
            }
        }
        return null;
    }
}
person Martin    schedule 07.10.2014
comment
Я реализовал это, но он по-прежнему не позволял щелкать область между текстом и стрелкой раскрывающегося списка в поле со списком, в котором включена функция IsEditable. Спасибо хоть. Я нашел полное решение, которое я опубликую здесь в ближайшее время - person Max; 11.10.2014

В итоге я нашел multiselectcombobox, который кто-то еще реализовал здесь:

http://www.telerik.com/support/code-library/a-multiselect-combobox

Мне не нужен был весь список со списком, так как он у нас уже был реализован, поэтому я просто посмотрел, как человек отображает пользовательское сообщение, когда для поля со списком IsEditable установлено значение false.

Посмотрев некоторое время на этот код и увидев, как я могу заставить его работать на меня, я поставил

<ucControls:RadComboBox.SelectionBoxTemplate> <DataTemplate> <TextBlock Text="{Binding Text,ElementName=RadCombo}" /> </DataTemplate> </ucControls:RadComboBox.SelectionBoxTemplate>

внутри XAML нашего собственного MultiSelectComboBox. (RadCombo — это имя конкретного элемента управления, с которым я хотел связать текст)

<ucControls:RadComboBox
    x:Name="RadCombo"
    Text=""
    ........

<ucControls:RadComboBox.SelectionBoxTemplate> <DataTemplate> <TextBlock Text="{Binding Text,ElementName=RadCombo}" /> </DataTemplate> </ucControls:RadComboBox.SelectionBoxTemplate>

    .......
</ucControls:RadComboBox>

Используя встроенный SelectionBoxTemplate, это просто добавило наложение TextBlock, а содержимое было привязано к собственному тексту RadComboBox, поэтому, когда мы устанавливали текст RadComboBox, TextBlock обновлялся.

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

Надеюсь, это поможет кому-то, удачи!

person Max    schedule 10.10.2014