Как изменить видимость элемента управления WPF из ViewModel

У меня есть приложение WPF, в котором я пытался реализовать шаблон MVVM и Prism 2. У меня есть Usercontrol, который подписался на событие, запущенное из другого Usercontrol. Я хотел бы переключить видимость нескольких дочерних элементов в элементе управления подпиской. События запускаются правильно, даже я могу успешно привязать данные к некоторым элементам. Как связать видимость или какое-либо свойство стиля с ViewModel и изменить их динамически.


person Raj    schedule 12.09.2009    source источник


Ответы (3)


У вас может быть логическое свойство в вашей ViewModel и связать это свойство со свойством Visibility ваших элементов управления. Поскольку вы будете назначать логическое значение, а свойство Visibility ожидает значение перечисления Visibility, вам придется использовать BooleanToVisibilityConverter для преобразования,

<Style.Resources>
     <BooleanToVisibilityConverter x:Key="booleanToVisibilityConverter" />
</Style.Resources>

<Image Visibility="{Binding Path=ShowImage, 
                    Converter={StaticResource booleanToVisibilityConverter}}"/>

Надеюсь это поможет.

Эсекьель Джадиб

person Ezequiel Jadib    schedule 12.09.2009
comment
Как-то у меня это не сработало. Я объявил конвертер в разделе Usercontrol.Resources и использовал привязки, как вы объяснили в комментарии. - person Raj; 13.09.2009

Хотя добавление логического свойства и использование преобразователя значений работает, я бы рекомендовал добавить свойство типа Visibility в вашу ViewModel, например

public Visibility ImageVisibility
{
    get { return shouldShowImage ? Visibility.Visible : Visibility.Collapsed }
}

Преимущество этого метода в том, что вам не нужно писать конвертер для каждого свойства, которое вы хотите выразить визуально (например, для уровня запасов, который окрашивает метку в красный цвет, когда он опускается ниже 10, у вас может быть конвертер, который вы используете один раз или просто предоставьте свойство StockLabelBrush из вашей виртуальной машины)

person Darren    schedule 24.04.2013
comment
Хотя этот ответ элегантен, в нем есть проблема. Если программа изменяет shouldShowImage, это изменение не отправляется в представление. - person James; 19.03.2014
comment
Это правда, но есть несколько способов решить эту проблему. Вы можете либо обработать событие PropertyChanged из shouldShowImage и вызвать новое событие PropertyChanged, либо разрешить доступ только к shouldShowImage через свойство оболочки, которое вызывает события для обоих свойств. - person Darren; 19.03.2014
comment
Я вижу, что здесь происходят две вещи: (i) я решаю, является ли что-то истинным или ложным (что кажется подходящим для виртуальной машины) и (ii) я беру это логическое значение и решаю, должен ли какой-то элемент управления быть видимым или нет ( что кажется подходящим для представления. Я бы подумал, что использование преобразователя здесь было бы идеальным с точки зрения поддержания чистоты границы V / VM. - person PeteH; 06.12.2018
comment
@PeteH, разница между ViewModel и Model заключается в том, что ViewModel касается того, что отображается в представлении. Без этой логики во ViewModel у вас будет просто модель. Кроме того, очень легко проверить, что элемент в представлении становится видимым при изменении логического значения, если логика находится в виртуальной машине. - person Darren; 06.12.2018

Есть простое решение для людей, которые сталкиваются с этой проблемой.

В своей модели представления создайте свойство «Видимость» следующим образом:

public Visibility ShowModifyButtons
    {
        get { return (Visibility)GetValue(ShowModifyButtonsProperty); }
        set { SetValue(ShowModifyButtonsProperty, value); }
    }

public static readonly DependencyProperty ShowModifyButtonsProperty =
        DependencyProperty.Register("ShowModifyButtons", typeof(Visibility), typeof(FileMatchViewModel),
        new UIPropertyMetadata(Visibility.Collapsed));

В своем XAML привяжите его так:

 <Button Focusable="False" Content="Save" Width="100" Margin="10" Visibility="{Binding ShowModifyButtons}"/>

Теперь в вашей модели представления вы можете установить ShowModifyButtons на Visibility.Collapsed или Visibility.Visible по мере необходимости.

person James    schedule 19.03.2014