2009-12-29 5 views
0

J'ai un DataTrigger récemment refacturé. Auparavant, le DataContext était ListBoxItem. Maintenant, il s'agit d'un ContentPresenter.WPF - Définition de DataContext pour un setter de déclencheur

Voici le code:

<DataTemplate.Triggers> 
    <DataTrigger Value="True"> 
     <DataTrigger.Binding> 
      <MultiBinding Converter="{StaticResource DisableWorkItemConverter}"> 
       <Binding ElementName="MainForm" Path="PickedWorkItemID"/> 
       <Binding Path="WorkItemForColumn.Id"/> 
      </MultiBinding> 
     </DataTrigger.Binding> 
     <Setter Property="IsEnabled" Value="False"/> 
     <Setter Property="loc:Main.IsCurrentItemEnabledChanged" Value="True"/> 
    </DataTrigger> 
</DataTemplate.Triggers> 

Dans le OnChange de IsCurrentItemEnabledChanged je peux voir que je peux obtenir au ListBoxItem avec le code suivant (dans le code sous-jacent):

listBoxItem = (ListBoxItem)Main.Instance.lstQueryResults.ItemContainerGenerator. 
       ContainerFromItem(((ContentPresenter)d).Content); 

Cependant , il n'y a aucun moyen que je peux voir pour définir le DataContext de telle sorte que mon Setter pour IsEnabled définira l'état activé du ListBoxItem plutôt que le ContentPresenter.

(je le ferais dans la OnChange de IsCurrentItemEnabledChanged, mais cette propriété est déjà un peu un hack et il ne sera pas réactiver l'élément lorsque le déclencheur est défini sur false.)

Toutes les idées?


Il a été suggéré que je fournir plus de fournir un contexte:

Voici mon XAML pour les modèles.

<DataTemplate x:Key="ColumnTemplate"> 
    <Border Name="ItemBorder" BorderBrush="Black" BorderThickness="1" CornerRadius="2" Padding="2"> 
     <WrapPanel>     
      <TextBlock Margin="0,0,5,0"> 
       <TextBlock.Text> 
        <Binding Path="Name" Converter="{StaticResource GetVisibilityOfColumnTitles}"/> 
       </TextBlock.Text> 
      </TextBlock> 
      <TextBlock Text="{Binding Value}" Margin="0,0,10,0" FontWeight="Bold" /> 
     </WrapPanel> 
    </Border> 
</DataTemplate> 

<DataTemplate x:Key="RowTemplate"> 
    <Border x:Name="ItemBorder" BorderThickness="1" BorderBrush="#D4D4FF"> 
     <Grid x:Name="ItemGrid" Width="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ItemsPresenter}}, Path=ActualWidth}" ScrollViewer.CanContentScroll="True" Margin="2"> 
      <Grid.ColumnDefinitions> 
       <ColumnDefinition Width="20" /> 
       <ColumnDefinition Width="*" /> 
       <ColumnDefinition Width="30" /> 
      </Grid.ColumnDefinitions> 
      <Grid.Background> 
       <Binding Path="WorkItemForColumn.Type" Converter="{StaticResource WorkItemTypeToColorConverter}" /> 
      </Grid.Background> 

      <CheckBox VerticalAlignment="Center" Grid.Column="0" IsChecked="{Binding 
             RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBoxItem}}, 
             Mode=TwoWay, Path=IsSelected}" Name="chkIsSelected" /> 

      <ItemsControl Grid.Column="1" Margin="5,0,5,0" ItemsSource="{Binding}" ItemTemplate="{StaticResource ColumnTemplate}" > 
       <ItemsControl.ItemsPanel> 
        <ItemsPanelTemplate> 
         <WrapPanel Orientation="Horizontal"></WrapPanel> 
        </ItemsPanelTemplate> 
       </ItemsControl.ItemsPanel> 
      </ItemsControl> 


      <Button HorizontalAlignment="Right" x:Name="btnPick" Grid.Column="3" Style="{StaticResource roundButton}" Width="15" Height="15" Tag="{Binding WorkItemForColumn.Id}" Margin="5,0,10,0"> 
       <Path Fill="DarkBlue"> 
        <Path.Data> 
         <PathGeometry> 
          <PathFigure StartPoint="2,0" IsClosed="True"> 
           <LineSegment Point="7,5"/> 
           <LineSegment Point="2,10"/> 
          </PathFigure> 
          <PathFigure StartPoint="2,2" IsClosed="True"> 
           <LineSegment Point="5,5"/> 
           <LineSegment Point="2,8"/> 
          </PathFigure> 
         </PathGeometry> 
        </Path.Data> 
       </Path> 
      </Button> 
     </Grid> 
    </Border> 
    <DataTemplate.Triggers> 
     <DataTrigger Value="True"> 
      <DataTrigger.Binding> 
       <MultiBinding Converter="{StaticResource DisableWorkItemConverter}"> 
        <Binding ElementName="MainForm" Path="PickedWorkItemID"/> 
        <Binding Path="WorkItemForColumn.Id"/> 
       </MultiBinding> 
      </DataTrigger.Binding> 
      <Setter Property="IsEnabled" Value="False"/> 
      <Setter Property="loc:Main.IsCurrentItemEnabledChanged" Value="True"/> 
     </DataTrigger> 
    </DataTemplate.Triggers> 
</DataTemplate> 

Voici le XAML pour la zone de liste:

<ListBox ScrollViewer.HorizontalScrollBarVisibility="Disabled" Button.Click="PickWorkItem_Click" SelectionMode="Multiple" ItemTemplate="{StaticResource RowTemplate}" Name="lstQueryResults" SelectionChanged="lstQueryResults_SelectionChanged" > 
    <ListBox.Resources> 
     <Style TargetType="{x:Type ListBoxItem}"> 
      <Style.Resources> 
       <SolidColorBrush x:Key="{x:Static SystemColors.HighlightTextBrushKey}" Color="Black"/> 
       <SolidColorBrush x:Key="{x:Static SystemColors.ControlTextBrushKey}" Color="Black"/> 
      </Style.Resources> 
     </Style> 
    </ListBox.Resources> 
</ListBox> 

Le DataContext est défini dans le Code comme ceci:

private void ChangeQueryResultListSource(WorkItemCollection queryResults, bool b) 
{ 
    // Un-hook the selection event while we change the ItemsSource 
    Form.ToggleOnSelectEvent(false); 

    // This sets the DataContext 
    QueryDisplay = GetDisplayValues(queryResults); 

    Form.QueryResultListSource = QueryDisplay; 
    // Rewire the selection events back in 
    Form.ToggleOnSelectEvent(true); 


    foreach (WorkItem item in Pad.Keys) 
    { 
     Form.SelectQueryResultItem(item); 
    } 
} 

private List<List<WorkItemColumn>> GetDisplayValues(WorkItemCollection queryResults) 
{ 
    var result = new List<List<WorkItemColumn>>(); 
    foreach (WorkItem workItem in queryResults) 
    { 
     var row = GetQueryColumns(queryResults.DisplayFields, workItem); 
     result.Add(row); 
    } 
    return result; 
} 

private List<WorkItemColumn> GetQueryColumns(DisplayFieldList fields, WorkItem workItem) 
{ 
    var row = new List<WorkItemColumn>(); 
    foreach (FieldDefinition column in fields) 
    { 
     var workItemColumn = new WorkItemColumn { Name = column.Name, Value = workItem[column.Name], WorkItemForColumn = workItem }; 
     row.Add(workItemColumn); 
    } 

    return row; 
} 

WorkItemColumn est une classe avec une paire nom-valeur et une référence aux données (objet WorkItem).

+0

Zoom un peu, montrer le code environnant, montrer toute la 'DataTemplate' et montre le contrôle qui l'utilise. –

+0

Ajout du code demandé. Merci d'avoir regardé ça. – Vaccano

+0

Je pourrais être le seul mais je suis un peu confus par votre question. "Cependant, il n'y a aucun moyen que je puisse voir pour définir le DataContext de telle sorte que mon Setter for IsEnabled définisse l'état activé du ListBoxItem plutôt que le ContentPresenter." – Ragepotato

Répondre

2

Désolé pour la réponse courte, mais vous devez déplacer la gâchette et la logique setter pour IsEnabled retour au ListBoxItem style:

<Style TargetType="{x:Type ListBoxItem}"> 
    <Style.Resources> 
     <SolidColorBrush x:Key="{x:Static SystemColors.HighlightTextBrushKey}" Color="Black"/> 
     <SolidColorBrush x:Key="{x:Static SystemColors.ControlTextBrushKey}" Color="Black"/> 
    </Style.Resources> 
    <Style.Triggers> 
     <DataTrigger Value="True"> 
      <DataTrigger.Binding> 
       <MultiBinding Converter="{StaticResource DisableWorkItemConverter}"> 
        <Binding ElementName="MainForm" Path="PickedWorkItemID"/> 
        <Binding Path="WorkItemForColumn.Id"/> 
       </MultiBinding> 
      </DataTrigger.Binding> 
      <Setter Property="IsEnabled" Value="False"/> 
     </DataTrigger> 
    </Style.Triggers> 
</Style> 
+0

Merci! C'est ce que j'ai fait! – Vaccano

Questions connexes