В 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.