В WPF MVVM при нажатии кнопки, как сделать так, чтобы мой вид что-то делал до или после ссылки Command на модель вида?

В одной форме у меня есть метка и кнопка редактирования. При нажатии кнопки "Изменить" шаблон элемента управления для метки изменяется, отображая текстовое поле и кнопку "Сохранить". Эта кнопка сохранения связана с командой сохранения на модели представления.

Мой вопрос / проблема заключается в том, что при нажатии кнопки "Сохранить" я хочу, чтобы шаблон элемента управления снова превратился в метку либо до, либо после выполнения команды в модели представления. В моем конкретном случае все, что ему нужно сделать, это установить для свойства на моем ярлыке значение True при каждом нажатии кнопки "Сохранить" в дополнение к выполняемой команде.

conv:ReadOnlyControlTemplate.DoLock="True"

ОБНОВЛЕНИЕ Я теперь намного ближе благодаря некоторым отзывам в ответах ниже. Я использую следующее для кнопки Сохранить:

<i:Interaction.Triggers>
                                        <ei:DataTrigger Comparison="Equal" Binding="{Binding Test, Converter={StaticResource TestConverter}, NotifyOnTargetUpdated=True, NotifyOnSourceUpdated=True, UpdateSourceTrigger=PropertyChanged}" Value="CommandUpdated"  >
                                            <ei:ChangePropertyAction  PropertyName="conv:ReadOnlyControlTemplate.DoLock" Value="True" TargetObject="{Binding ElementName=ShiftManagerMessages}" /> 
                                        </ei:DataTrigger>
                                    </i:Interaction.Triggers>

Изменение на TargetObject с TargetName объекта ei:ChangePropertyAction заставило его правильно увидеть метку. Однако теперь я получаю следующую ошибку:

{"Не удается найти свойство с именем \"conv:ReadOnlyControlTemplate.DoLock\"для типа \" Метка \"."}

Я могу указать на другие свойства, только не на это, и я не понимаю, почему?

3 ответа

Решение

Пример использования DataTrigger для управления шаблоном:

<UserControl x:Class="NextPlc.Instore.Epos.Till.UserControl1"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
            xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" 
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions" 
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">
<UserControl.Resources>
    <ControlTemplate TargetType="Label" x:Key="ReadOnlyTemplate"></ControlTemplate>
    <ControlTemplate TargetType="Label" x:Key="EditTemplate"></ControlTemplate>
</UserControl.Resources>
<i:Interaction.Triggers>
    <ei:DataTrigger Binding="{Binding IsReadOnly}" Value="True">
        <ei:DataTrigger.Actions>
            <ei:ChangePropertyAction TargetName="label" PropertyName="Template" Value="{StaticResource ReadOnlyTemplate}"/>
        </ei:DataTrigger.Actions>
    </ei:DataTrigger>
    <ei:DataTrigger Binding="{Binding IsReadOnly}" Value="False">
        <ei:DataTrigger.Actions>
            <ei:ChangePropertyAction TargetName="label" PropertyName="Template" Value="{StaticResource EditTemplate}"/>
        </ei:DataTrigger.Actions>
    </ei:DataTrigger>
</i:Interaction.Triggers>
<Grid>
    <Label x:Name="label">
    </Label>
</Grid>

Не уверен, что я правильно понял проблему, но вы можете запустить некоторый код в своем представлении, подписавшись на различные (предварительные) события mousedown вашей кнопки и изменив там свой макет. То есть, если вы против использования кода в проекте MVVM. Ваша кнопка активирует как обработчик команд в вашей виртуальной машине, так и обработчик событий в вашем представлении.

<Button MouseDown="Button_MouseDown" Command="{Binding SaveCommand}" />

 private void Button_MouseDown(object sender, System.Windows.RoutedEventArgs e)
 {
    // Set your property
 }

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

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

Делая это с DataTrigger - добавьте ссылку на Microsoft.Expressions.Interactions, затем добавьте XAML...

xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions" 

в вашем пространстве имен, то...

<i:Interaction.Triggers>
    <ei:DataTrigger Binding="{Binding ViewModel.State}" Value="CommandUpdated">
         <Setter Property="Foreground" Value="Red" />
    </ei:DataTrigger>
</i:Interaction.Triggers>

Это работает путем запуска на основе свойства 'State' в модели представления. В этом случае состояние является перечислением, где CommandUpdated является значением этого перечисления - это может быть как bool, так и int.

Другие вопросы по тегам