2010-02-22 2 views
1

Je suis assez nouveau pour WPF alors excusez-moi pour toute question stupide ...Comment se binded ListboxItems de ListView dans WPF

J'ai un ListView avec trois colonnes qui binded à une source de XmlDataProvider comme ce qui suit :

 <XmlDataProvider x:Key="Properties" XPath="/Info"> 
     <x:XData> 
      <Info xmlns=""> 
       <Property Name="Text" Value=""/>    <!--0--> 
       <Property Name="Tooltip" Value=""/>    <!--1--> 
       <Property Name="Enable" Value=""/>    <!--2--> 
       <Property Name="Visible" Value=""/>    <!--3--> 
       <Property Name="Focus" Value=""/>    <!--4--> 
       <Property Name="Selected" Value=""/>   <!--5--> 
       <Property Name="Count" Value=""/>    <!--6--> 
       <Property Name="Item" Value=""/>    <!--7--> 
       <Property Name="SelectedText" Value=""/>  <!--8--> 
       <Property Name="SelectedIndex" Value=""/>  <!--9--> 
       <Property Name="Complete" Value=""/>   <!--10--> 
      </Info> 
     </x:XData> 
    </XmlDataProvider> 

ListView est défini comme suit:

 <ListView Name="lstProperties" Margin="55 0 0 0" Style="{DynamicResource TsListView}" 
     Grid.Row="2" Grid.RowSpan="7" Grid.ColumnSpan="4" 
     ItemsSource="{Binding Source={StaticResource Properties}, XPath=Property}" 
     ItemContainerStyle="{DynamicResource TsListViewItem}" 
     ScrollViewer.HorizontalScrollBarVisibility="Hidden" 
     SelectionMode="Single" IsEnabled="False" 
     SelectionChanged="propertySelected" 
     > 

     <ListView.View> 
      <GridView AllowsColumnReorder="False"> 
       <GridViewColumn CellTemplate="{StaticResource FirstCell}" Width="25" /> 
       <GridViewColumn Header="Property" Width="80"> 
       <GridViewColumn.CellTemplate> 
        <DataTemplate> 
         <Label Style="{DynamicResource TsLabel}" Height="25" Width="115" Content="{Binding [email protected]}" /> 
        </DataTemplate> 
       </GridViewColumn.CellTemplate> 
        </GridViewColumn> 
       <GridViewColumn Header="Value" Width="130"> 
        <GridViewColumn.CellTemplate> 
         <DataTemplate> 
          <TextBox Style="{DynamicResource TsHelperTextBox}" 
            Height="20" Width="115" Text="{Binding [email protected]}" 
            IsEnabled="{Binding ElementName=rbTypeAssert, Path=IsChecked}" GotFocus="gridTextBox_GotFocus" /> 
         </DataTemplate> 
        </GridViewColumn.CellTemplate> 
       </GridViewColumn> 
      </GridView> 
     </ListView.View> 
    </ListView> 

Ce que je veux faire maintenant est assez simple: Je veux juste activer/désactiver certaines des ListViewItems. La seule manière que je trouvais pour obtenir ListViewItems est par la méthode suivante:

lstProperties.ItemContainerGenerator.ContainerFromIndex(index) 

Cela me fait un peu mal à l'aise. Je devrais obtenir les articles par la propriété de nom de propriété. Est-ce qu'il y a un moyen de faire ça? J'ai également des problèmes lorsque j'essaie de le faire juste après l'initialisation de la fenêtre. Je reçois une exception NullReferenceException lorsque j'essaie de désactiver l'un de ces ListViewItems. Il semble que juste après que la fenêtre soit rendue, la liaison n'est pas encore terminée.

Répondre

0

Eh bien vos commentaires, associés à d'autres commentaires reçus , m'a permis de résoudre le problème. Merci beaucoup! Ce que j'ai fait était d'ajouter un nouvel attribut, nommé IsEnable, à la propriété dans le XmlDataProvider, puis j'ai lié la propriété IsEnabled de ListViewItem à ce nouvel attribut. Ainsi, au lieu d'avoir une propriété globale pour définir l'état de tous les ListViewItems, comme vous l'avez suggéré, j'aurai des "binds individuels".

Pour modifier les données par programme je la méthode suivante:

provider.Document.SelectSingleNode("//Property[Name=\"Text\"]/IsEnable").InnerText = false.ToString(); 

Cette méthode nécessite un format légèrement différent pour les données. Ainsi le XmlDataProvider est maintenant comme suit:

 <XmlDataProvider x:Key="Properties" XPath="/Info" IsAsynchronous="False" IsInitialLoadEnabled="True"> 
     <x:XData> 
      <Info xmlns=""> 
       <Property> 
        <Name>Text</Name> 
        <Value></Value> 
        <IsEnable>true</IsEnable> 
       </Property> 
       <Property> 
        <Name>Tooltip</Name> 
        <Value></Value> 
        <IsEnable>true</IsEnable> 
       </Property> 
       <Property> 
        <Name>Enable</Name> 
        <Value></Value> 
        <IsEnable>true</IsEnable> 
       </Property> 
       <Property> 
        <Name>Visible</Name> 
        <Value></Value> 
        <IsEnable>true</IsEnable> 
       </Property> 
       <Property> 
        <Name>Focus</Name> 
        <Value></Value> 
        <IsEnable>true</IsEnable> 
       </Property> 
       <Property> 
        <Name>Selected</Name> 
        <Value></Value> 
        <IsEnable>true</IsEnable> 
       </Property> 
       <Property> 
        <Name>Count</Name> 
        <Value></Value> 
        <IsEnable>true</IsEnable> 
       </Property> 
       <Property> 
        <Name>Item</Name> 
        <Value></Value> 
        <IsEnable>true</IsEnable> 
       </Property> 
       <Property> 
        <Name>SelectedText</Name> 
        <Value></Value> 
        <IsEnable>true</IsEnable> 
       </Property> 
       <Property> 
        <Name>SelectedIndex</Name> 
        <Value></Value> 
        <IsEnable>true</IsEnable> 
       </Property> 
       <Property> 
        <Name>Complete</Name> 
        <Value></Value> 
        <IsEnable>true</IsEnable> 
       </Property> 
      </Info> 
     </x:XData> 
    </XmlDataProvider> 

Merci encore pour votre contribution! José Tavares

1

Le plus simple et la meilleure façon de le faire est d'exposer une propriété qui détermine si le ListViewItem doit être activé ou non, puis se lier à elle:

<ListView> 
    <ListView.ItemContainerStyle> 
     <Style TargetType="ListViewItem"> 
      <Setter Property="IsEnabled" Value="{Binding YourProperty}"/> 
     </Style> 
    </ListView.ItemContainerStyle> 
</ListView> 
+0

Merci, je l'ai pensé à quelque chose comme ça mais j'ai eu trois problèmes avec cette approche. 1. Comment définir une propriété personnalisée (OK c'est vraiment une question de débutant) 2. J'ai déjà un style défini pour tous les ListViewItems sur mon application. Est-ce que votre solution signifie que je dois avoir un style spécifique pour ces ListViewItems ?, et le plus important, 3. Dans cette situation particulière, j'ai besoin d'une propriété par ListViewItem et pas une propriété générale. Puis-je lier cela à partir de XmlDataSource? Merci – jpsstavares

1

Kents réponse est correcte, mais j'utiliser un convertisseur, au lieu d'élargir votre modèle:

<ListView> 
    <ListView.ItemContainerStyle> 
     <Style TargetType="ListViewItem"> 
      <Setter Property="IsEnabled" Value="{Binding Converter={StaticResource IsEnabledConverter}}"/> 
     </Style> 
    </ListView.ItemContainerStyle> 
</ListView> 

Et le convertisseur:

public class IsEnabledConverter : IValueConverter 
{ 
    #region IValueConverter Members 

    public object Convert(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     //Implement your logic here, and return true/false accordingly 
     return true; 
    } 

    public object ConvertBack(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     throw new System.NotImplementedException(); 
    } 

    #endregion 
} 
+0

Eh bien, je vois cela fonctionne bien que je pense que je préfère la solution que j'ai obtenue parce que la liaison est plus claire et ne nécessite pas de code supplémentaire. Mais merci pour le conseil, il peut être utile pour moi dans d'autres situations. – jpsstavares