2009-08-24 12 views
0

J'ai un ListView dans un Windows Form auquel je lie une liste d'objets à la création du formulaire. Ce que je voudrais faire est sur une boucle de clic de bouton par les articles qui ont été créés et change leur propriété IsEnabled à faux. J'ai essayé deux méthodes et aucune d'elles n'a été particulièrement réussie. Quelqu'un peut-il aider à résoudre ces problèmes et/ou suggérer une autre méthode?Mise en boucle via WPF Articles ListView DateTemplate

Mon ListView XAML

<ListView Margin="6" Name="myListView" ItemsSource="{Binding Path=.}"> 
    <ListView.ItemTemplate> 
     <DataTemplate> 
     <Grid> 
      <Grid.ColumnDefinitions> 
       <ColumnDefinition Width="10"/> 
       <ColumnDefinition Width="350"/> 
       <ColumnDefinition Width="20"/> 
       <ColumnDefinition Width="350"/> 
      </Grid.ColumnDefinitions> 
      <Grid.RowDefinitions> 
       <RowDefinition Height="30" /> 
       <RowDefinition Height="30" /> 
       <RowDefinition Height="30" /> 
      </Grid.RowDefinitions> 
      <TextBlock Name="ItemNameTextBlock" Grid.Row="0" Grid.Column="1" Grid.ColumnSpan="4" VerticalAlignment="Center" Text="{Binding Path=ItemName}" /> 
      <CheckBox Name="Action1CheckBox" Grid.Row="1" Grid.Column="1" Content="Action1" IsChecked="True" /> 
      <CheckBox Name="Action2CheckBox" Grid.Row="1" Grid.Column="3" Content="Action2" IsChecked="True" /> 
      <TextBox Height="23" Name="MyInputTextBox" Grid.Row="2" Grid.Column="1" Margin="2,0,2,0" VerticalAlignment="Top" Width="25" Text="{Binding Path=DataValue}" />           
     </Grid> 
     </DataTemplate> 
    </ListView.ItemTemplate> 
</ListView> 

Objectif: Sur pression du bouton (d'un bouton sans lien) désactiver les cases à cocher et la zone de texte

Tentative 1: Cela ne fonctionne pas, les articles sont les databound articles et je ne peux pas trouver un moyen d'arriver aux contrôles eux-mêmes pour faire quelque chose comme ça. Est-ce seulement possible?

foreach (var item in ReleaseDeployProcessListView.Items) 
{ 
    ((CheckBox)item.FindControl("Action1CheckBox")).IsEnabled = false; 
} 

Tentative 2: J'ai ajouté une propriété publique « IsFormElementsEnabled » à la forme et sur le bouton, cliquez définir cette valeur à false. Mais je ne pouvais pas comprendre comment/si/ce que je devais faire pour lier cela aux éléments. J'ai essayé IsEnabled = "{Binding Path = IsFormElementsEnabled} (qui ne fonctionne pas car il est lié aux objets et qui n'est pas partie de ces obects) et j'ai essayé IsEnabled =" {Binding Path = this.IsFormElementsEnabled} (qui doesn ne semble pas fonctionner non plus)

Répondre

2

Vous pouvez toujours ajouter un booléen sur votre ViewModel et le lier à votre CheckBox?

Alors, imaginez le booléen suivant sur votre vue Modèle:

public bool CanEdit 
{ 
    get 
    { 
     return canEdit; 
    } 
    set 
    { 
     canEdit = value; 
     NotifyPropertyChanged("CanEdit"); 
    } 
} 

public event PropertyChangedEventHandler PropertyChanged; 
private void NotifyPropertyChanged(string info) 
{ 
    if (this.PropertyChanged != null) 
    { 
     this.PropertyChanged(this, new PropertyChangedEventArgs(info)); 
    } 
} 

Notez également que votre ViewModel doit implémenter l'interface INotifyPropertyChanged

lient ensuite ce booléen à la case située dans votre DataTemplate

<CheckBox Name="Action1CheckBox" Grid.Row="1" Grid.Column="1" Content="Action1" IsChecked="True" IsEnabled="{Binding CanEdit}" /> 

Et dans votre ensemble de boucles for le booléen de CanEdit est faux:

foreach (var item in ReleaseDeployProcessListView.Items) 
{ 
    item.CanEdit = false; 
} 
+0

Oui, cela serait certainement travailler, je j'espérais vraiment pu obtenir l'un des deux autres mécanismes pour travailler cependant. – ChrisHDog

+1

Voir ma nouvelle réponse;) Bien que je préfère encore cette méthode si :) – Arcturus

2

Ok ici est de savoir comment faire vos deux solutions fonctionnent;)

Tentative un:

foreach (var item in ReleaseDeployProcessListView.Items) 
{ 
    ListViewItem i = (ListViewItem) ReleaseDeployProcessListView.ItemContainerGenerator.ContainerFromItem(item); 

    //Seek out the ContentPresenter that actually presents our DataTemplate 
    ContentPresenter contentPresenter = FindVisualChild<ContentPresenter>(i); 

    CheckBox checkbox = (CheckBox)i.ContentTemplate.FindName("Action1CheckBox", contentPresenter); 
    checkbox.IsEnabled = false; 
} 


private T FindVisualChild<T>(DependencyObject obj) 
    where T : DependencyObject 
{ 
    for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++) 
    { 
     DependencyObject child = VisualTreeHelper.GetChild(obj, i); 
     if (child != null && child is T) 
      return (T)child; 
    } 

    for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++) 
    { 
     DependencyObject child = VisualTreeHelper.GetChild(obj, i); 
     T childOfChild = FindVisualChild<T>(child); 
     if (childOfChild != null) 
      return childOfChild; 
    } 

    return null; 
} 

Tentative deux:

propriété de dépendance sur votre commande principal:

public bool IsFormElementsEnabled 
{ 
    get { return (bool)GetValue(IsFormElementsEnabledProperty); } 
    set { SetValue(IsFormElementsEnabledProperty, value); } 
} 

public static readonly DependencyProperty IsFormElementsEnabledProperty = 
    DependencyProperty.Register("IsFormElementsEnabled", typeof(bool), typeof(YourClass), new PropertyMetadata(true)); 

Ensuite, utilisez les liaisons RelativeSource à votre classe principale dans vos contrôles CheckBox:

<CheckBox Name="Action1CheckBox" Grid.Row="1" Grid.Column="1" Content="Action1" IsChecked="True" 
      IsEnabled="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:YourControl}}, Path=IsFormElementsEnabled}" /> 

Comme vous pouvez voir de nombreux chemins mènent à Rome;) Je préférerais utiliser la première option cependant, car il pourrait faire partie de quelque chose de votre logique métier par exemple un booléen qui détermine si un client a déjà payé ou quelque chose comme ça: CustomerHasPaid

Hope this helps

+0

Merci beaucoup Arcturus, réponse parfaite à ma question. Je suis d'accord que l'autre réponse est probablement meilleure (et je l'ai marquée comme correcte), mais j'étais très curieux de savoir comment ces deux autres méthodes pourraient être accomplies. Merci encore! – ChrisHDog

+0

Pas de problème .. content de pouvoir aider;) – Arcturus