Цикл по элементам DateFemplate WPF ListView - PullRequest
0 голосов
/ 24 августа 2009

У меня есть ListView в форме Windows, к которому я привязываю список объектов при создании формы. То, что я хотел бы сделать, это щелкнуть по кнопке через элементы, которые были созданы, и изменить их свойство IsEnabled на false. Я пробовал два метода, и ни один из них не был особенно успешным. Кто-нибудь может помочь исправить это и / или предложить альтернативный метод?

Мой 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>

Цель: при нажатии кнопки (не связанной кнопки) отключить флажки и текстовый блок

Попытка 1: Это не сработало, Предметы - это элементы с привязкой к данным, и я не могу найти способ добраться до элементов управления, чтобы сделать что-то подобное. Это вообще возможно?

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

Попытка 2: Я добавил открытое свойство "IsFormElementsEnabled" в форму и по нажатию кнопки установил для этого значения значение false. Но я не мог понять, как / если / что мне нужно было сделать, чтобы связать это с предметами. Я попытался IsEnabled = "{Binding Path = IsFormElementsEnabled} (который не работает, так как он связан с объектами, и который не является стороной этих объектов), и я попытался IsEnabled =" {Binding Path = this.IsFormElementsEnabled} (который не Кажется, тоже не работает)

Ответы [ 2 ]

2 голосов
/ 24 августа 2009

Хорошо, вот как заставить ваши решения работать;)

Попытка первая:

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;
}

Попытка два:

Свойство зависимости от вашего основного элемента управления:

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));

Затем используйте привязки RelativeSource к вашему основному классу в элементах управления 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}" />

Как вы можете видеть, многие дороги ведут в Рим;) Я бы предпочел использовать первый вариант, потому что он может быть частью вашей бизнес-логики, например логическим, который определяет, заплатил ли клиент уже или что-то в этом роде : CustomerHasPaid

Надеюсь, это поможет

2 голосов
/ 24 августа 2009

Вы всегда можете добавить логическое значение в ViewModel и связать его с CheckBox?

Итак, представьте следующее логическое значение для вашей модели View:

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));
    }
} 

Также обратите внимание, что ваша ViewModel должна реализовывать интерфейс INotifyPropertyChanged

Затем привяжите это логическое значение к CheckBox в вашем шаблоне данных

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

И в вашем цикле for установите логическое значение CanEdit, равное false:

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