循环通过WPF ListView DateTemplate项目

时间:2009-08-24 08:48:42

标签: wpf winforms data-binding listview loops

我在Windows窗体中有一个ListView,我在创建表单时绑定了一个对象列表。我想要做的是在按钮上单击循环创建的项目并将其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>

目标:按下按钮(无关按钮)禁用CheckBoxes和TextBox

尝试1: 这不起作用,Items是数据绑定项,我无法找到一种方法来控制自己做这样的事情。这甚至可能吗?

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 个答案:

答案 0 :(得分:2)

您总是可以在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接口

然后将此布尔值绑定到DataTemplate中的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;
}

答案 1 :(得分:2)

好的,这里是如何让你的解决方案都有效;)

尝试一次:

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

然后在CheckBox控件中使用RelativeSource绑定到主类:

<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

希望这有帮助