我在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}(这不是似乎也工作了)
答案 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
希望这有帮助