2013-02-20 1 views
1

Я использую VS 2012, с WPF 4.5WPF Как добавить триггер смеси взаимодействия в стиле ресурс

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

В частности, я хочу использовать EventToCommand, который поставляется с инфраструктурой MVVM-Light, и вставлять его в текстовый стиль и присоединяться к событию LostFocus текстового поля. Я планирую использовать это, чтобы отметить определенные текстовые поля с ValidationStyle, который запускает связанную команду (в режиме просмотра) в событие LostFocus текстового поля. Этот стиль проверки будет использовать IDataErrorInfo для отображения ошибок пользователю через пользовательский интерфейс.

Этот вопрос похож на следующие вопросы (но они не имеют общего решения):

EventToCommand in button style

How to add a Blend Behavior in a Style Setter

ВОПРОС: Как я могу добавить эклектичным EventToCommand к потерянный фокус текстового поля, связанный с командой в файле viewmodel datacontext (я не хочу использовать код или прикрепленное свойство, я хочу, чтобы он был полностью определен в XAML)?

ответ

2

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

Я использую модель MVVM для своего приложения, поэтому я не хочу иметь код за страницами xaml. Я также хотел, чтобы привязка текстового поля к свойствам IDataErrorInfo, где проверка для этого текстового поля запускается через событие lostfocus в текстовом поле. Это событие будет привязано к команде ретрансляции в режиме просмотра, которая будет проверять применимый объект и добавлять реальные ошибки.

Так что мне нужно, чтобы текстовое поле lostfocus eventcommand принимало имя текстового поля (которое соответствует именам столбцов из базы данных) в качестве параметра команды.

Вот снимок экрана, что я пытаюсь сделать WPF Screen Shot of Textbox Validation STyle

Вот как я это сделал:

Сначала я определил команду на модели представления:

Imports GalaSoft.MvvmLight.Command 
Private _LostFocusValidateCommand As RelayCommand(Of String) 

    Public ReadOnly Property LostFocusValidateCommand() As RelayCommand(Of String) 
     Get 
      If _LostFocusValidateCommand Is Nothing Then 
       _LostFocusValidateCommand = New RelayCommand(Of String)(AddressOf LostFocusValidateExecute) 
      End If 
      Return _LostFocusValidateCommand 
     End Get 
    End Property 
    Private Sub LostFocusValidateExecute(sParam As String) 
     NewClient.PropertyValitaion(False, sParam) 
    End Sub 

здесь это проверка свойств с использованием IDataErrorInfo (я упустил базовую реализацию IDataErrorInfo для экономии места, оставьте комментарий, если вы хотите, чтобы я опубликовал его)

Public Sub PropertyValitaion(bAllProperties As Boolean, Optional sProperty As String = "") 
    'initialize validation helper 
    Dim vhelper As New ValidationHelper 

    If bAllProperties Or sProperty = "chrCompany" Then 
     If String.IsNullOrEmpty(chrCompany) Then 
      AddError("chrCompany", "You must enter a Company Name") 
     Else 
      RemoveError("chrCompany") 
     End If 
    End If 
    If bAllProperties Or sProperty = "chrFirst" Then 
     If String.IsNullOrEmpty(chrFirst) Then 
      AddError("chrFirst", "You must enter a First Name") 
     Else 
      RemoveError("chrFirst") 
     End If 
    End If 
    If bAllProperties Or (sProperty = "chrPhone1" Or sProperty = "chrPhone1Ext") Then 
     If String.IsNullOrEmpty(Trim(chrPhone1Ext)) = False And String.IsNullOrEmpty(Trim(chrPhone1)) Then 
      Me.AddError("chrPhone1", "Provide a phone number or remove extension") 
     Else 
      RemoveError("chrPhone1") 
     End If 
     If String.IsNullOrEmpty(Trim(chrPhone1)) = False Then 
      If vhelper.CheckPhoneNumber(Me.chrPhone1) = False Then 
       Me.AddError("chrPhone1", "Phone 1 format invalid") 
      Else 
       RemoveError("chrPhone1") 
      End If 
     End If 
    End If 

End Sub 

Жесткая часть выясняла, как определить стиль. Стиль давно, извините, радостей «читаемым» XML:

<Style x:Key="FTC_ValidateTextBox" BasedOn="{x:Null}" TargetType="{x:Type TextBox}"> 
    <Style.Setters> 
     <Setter Property="FontFamily" Value="Open Sans Condensed"/> 
     <Setter Property="FontSize" Value="19" /> 
     <Setter Property="Margin" Value="3,3,15,6"/> 
     <Setter Property="Padding" Value="10,3"/> 
     <Setter Property="TextWrapping" Value="Wrap" /> 
     <Setter Property="HorizontalAlignment" Value="Stretch" /> 
     <Setter Property="VerticalAlignment" Value="Center" /> 
     <Setter Property="Background" Value="{StaticResource DetailTextBox}" /> 
     <Setter Property="BorderBrush" Value="{StaticResource MediumGray}" /> 
     <Setter Property="BorderThickness" Value="1" /> 
     <Setter Property="Foreground" Value="Black" /> 
     <Setter Property="AllowDrop" Value="true"/> 
     <Setter Property="FocusVisualStyle" Value="{x:Null}"/> 
     <Setter Property="ScrollViewer.PanningMode" Value="VerticalFirst"/> 
     <Setter Property="Stylus.IsFlicksEnabled" Value="False"/> 
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate TargetType="{x:Type TextBox}"> 
        <Border Name="Bd" SnapsToDevicePixels="true" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}"> 
         <ScrollViewer x:Name="PART_ContentHost" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"> 
          <i:Interaction.Triggers> 
           <i:EventTrigger EventName="LostFocus"> 
            <cmd:EventToCommand Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}},Path=DataContext.LostFocusValidateCommand}" 
                 CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type TextBox}},Path=Name}"/> 
           </i:EventTrigger> 
          </i:Interaction.Triggers> 
         </ScrollViewer> 
        </Border> 
        <ControlTemplate.Triggers> 
         <Trigger Property="IsEnabled" Value="false"> 
          <Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/> 
          <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/> 
         </Trigger> 
        </ControlTemplate.Triggers> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
     <Setter Property="Validation.ErrorTemplate"> 
      <Setter.Value> 
       <ControlTemplate> 
        <Border BorderBrush="{StaticResource MediumRed}" > 
         <Grid> 
          <Grid.RowDefinitions> 
           <RowDefinition Height="Auto" /> 
           <RowDefinition Height="Auto" /> 
          </Grid.RowDefinitions> 
          <AdornedElementPlaceholder Name="parentTextBox" /> 
          <TextBlock Grid.Row="1" Style="{StaticResource FTC_DetailError}" 
             Text="{Binding ElementName=parentTextBox, Path=AdornedElement.(Validation.Errors).CurrentItem.ErrorContent}"/> 
         </Grid> 
        </Border> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style.Setters> 
    <Style.Triggers> 
     <Trigger Property="Validation.HasError" Value="true"> 
      <Setter Property="ToolTip" Value="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=(Validation.Errors).CurrentItem.ErrorContent}"/> 
      <Setter Property="BorderBrush" Value="{StaticResource MediumRed}"/> 
      <Setter Property="Foreground" Value="{StaticResource MediumRed}"/> 
      <Setter Property="Margin" Value="3,3,15,31"/> 
     </Trigger> 
    </Style.Triggers> 
</Style> 

<Style x:Key="FTC_DetailError" TargetType="TextBlock"> 
    <Style.Setters> 
     <Setter Property="FontFamily" Value="Open Sans Condensed"/> 
     <Setter Property="Control.FontWeight" Value="Light" /> 
     <Setter Property="Foreground" Value="{StaticResource TitleWhite}"/> 
     <Setter Property="FontSize" Value="15" /> 
     <Setter Property="Margin" Value="0"/> 
     <Setter Property="Padding" Value="10,3"/> 
     <Setter Property="HorizontalAlignment" Value="Stretch"/> 
     <Setter Property="Background" Value="{StaticResource MediumRed}"/> 
    </Style.Setters>    
</Style> 

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

> xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" 
> xmlns:cmd="http://www.galasoft.ch/mvvmlight" 

все волшебство происходит в свойстве шаблона, который определяет шаблон элемента управления. Вы не можете обернуть i: взаимодействие в самом шаблоне управления, оно должно содержаться в производном объекте, почти на самом деле, границе, scrollviewer, wrappanel и т. Д. Затем вы устанавливаете триггер вентиляции и свойства команды. Они должны быть достаточно легкими, чтобы следовать, я передаю имя текстового поля в качестве параметра команды. Клиентский «ящик», который вы видите на снимке экрана, представляет собой сетку с контекстом данных, установленным для нового свойства объекта-клиента родительской модели. SO, чтобы получить доступ к команде в родительской модели просмотра, мне пришлось ссылаться на datacontext родителя и вызвать свойство command.

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

Cheers

 Смежные вопросы

  • Нет связанных вопросов^_^