Вопрос по mvvm, c#, xaml, isenabled, wpf – Как установить IsReadOnly / IsEnabled на весь контейнер, такой как Panel или GroupBox, используя XAML?

4

у меня естьMVVM приложение, которое содержит несколько представлений с некоторыми сложнымиIsReadOnly правила, основанные на разрешениях пользователя, режиме просмотра / редактирования и состоянии объекта.

Я хотел бы установитьIsReadOnly и / илиIsEnabled свойства для целых групп элементов управления в одном контейнере (GroupBox / StackPanel / Grid / UserControl / так далее.). Значение этого свойства будет определено во ViewModel.

У меня 3-6 разныхSomeGroupIsReadOnly свойства для UserControl (с большим количеством элементов управления вводом, таких какTextBox, RadioButtons, ComboBoxes и немногоDataGrids) и я ищу общий вид,MVVMудобное решение, которое позволит мне повторно использовать привязки для каждого контейнера, а не указывать их отдельно для каждого отдельного элемента управления.

How can I set IsReadOnly / IsEnabled on all controls inside container like Panel or GroupBox using XAML?

Похоже, что WPF поддерживает это "из коробки" ...

EDIT

Я забыл упомянуть, что установка IsEnabled для контейнера отключает важную функцию TextBoxes - возможность копировать их содержимое. Мне нужно, чтобы они были вIsReadOnly=true государство. Если бы для этого был обходной путь, моя проблема была бы решена.

Это лучшее решение, которое я нашел:dkowalski.com/blog/archive/2010/02/04/… surfen

Ваш Ответ

2   ответа
6

Что-то, что нам хорошо сработало, - это определить модель представления, которая представляет структуру разрешений вашего приложения (YourPermissionsViewModel в моем примере ниже).

Затем вы можете создать пользовательский элемент управления панели, который расширяет любую панель по вашему выбору (StackPanel в этом примере). Таким образом, вы можете добавить привязки свойств IsReadOnly и сохранить их для дочерних элементов панели.

Вот как может выглядеть панель в XAML:

<local:PanelExtension IsEnabled="{Binding YourPermissionsViewModel.IsEnabled}" 
                      IsReadOnly="{Binding YourPermissionsViewModel.IsReadOnly}">
    <TextBox Text="eeny" Width="100" />
    <TextBox Text="meeny" Width="100"/>
    <TextBox Text="miny" Width="100"/>
    <TextBox Text="mo" Width="100" />
    <Label Content="coolio" Width="100" />
</local:PanelExtension>

А вот элемент управления расширением StackPanel, содержащий все функции StackPanel, а также присоединение настраиваемого свойства зависимостей IsReadOnly, которое обновляет соответствующее значение свойства для всех дочерних элементов управления, обладающих этим свойством:

public class PanelExtension : StackPanel
{
    public bool IsReadOnly
    {
        get { return (bool)GetValue(IsReadOnlyProperty); }
        set { SetValue(IsReadOnlyProperty, value); }
    }
    public static readonly DependencyProperty IsReadOnlyProperty =
        DependencyProperty.Register("IsReadOnly", typeof(bool), typeof(PanelExtension),
        new PropertyMetadata(new PropertyChangedCallback(OnIsReadOnlyChanged)));

    private static void OnIsReadOnlyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        ((PanelExtension)d).OnIsReadOnlyChanged(e);
    }

    protected virtual void OnIsReadOnlyChanged(DependencyPropertyChangedEventArgs e)
    {
        this.SetIsEnabledOfChildren();
    }

    public PanelExtension()
    {
        this.Loaded += new RoutedEventHandler(PanelExtension_Loaded);
    }

    void PanelExtension_Loaded(object sender, RoutedEventArgs e)
    {
        this.SetIsEnabledOfChildren();
    }

    private void SetIsEnabledOfChildren()
    {
        foreach (UIElement child in this.Children)
        {
            var readOnlyProperty = child.GetType().GetProperties().Where(prop => prop.Name.Equals("IsReadOnly")).FirstOrDefault();
            readOnlyProperty.SetValue(child, this.IsReadOnly, null);
        }
    }
}

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

Спасибо за ответ, мне нравится идея инкапсуляции разрешений вYourPermissionsViewModel, Я попробую. surfen
9

Отключение панели, содержащей ваши элементы управления, также отключит элементы управления внутри панели. Свяжите элемент IsEnabled в Panel со свойством bool в ViewModel и установите его в соответствии с вашими правилами, чтобы отключить Panel и всех ее дочерних элементов.

Xaml:

<GroupBox IsEnabled="{Binding Path=IsGroupEnabled}">
    <StackPanel>
        <Button Content="Sample Button"/>
        <TextBox Text="Sample text box"/>
    </StackPanel>
</GroupBox>
+1 Да, это работает. Но это также отключило TextBox, поэтому пользователь не может скопировать содержимое. Я хотел бы, чтобы TextBox былIsReadOnly=true, Я отредактировал вопрос. surfen
Я хотел бы создать инвертированный логический преобразователь и связать его с TextBox, используя для преобразования значение IsGroupEnabled. Это хороший SO сообщение об этом:stackoverflow.com/questions/1039636/…

Похожие вопросы