我有以下ListView:
<ListView Name="listView">
<ListView.View>
<GridView>
<GridView.ColumnHeaderContainerStyle>
<Style TargetType="{x:Type GridViewColumnHeader}">
<Setter Property="Visibility"
Value="Collapsed"/>
</Style>
</GridView.ColumnHeaderContainerStyle>
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<StackPanel>
<CheckBox
Margin="0"
VerticalAlignment="Center"
IsChecked="{Binding IsChecked}"
Visibility="{Binding IsChecked, Converter={StaticResource boolToVis}}">
</CheckBox>
</StackPanel>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Margin="0"
Text="{Binding Text}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
ListView中的项目属于以下类型:
public class CheckBoxListViewItemSource : INotifyPropertyChanged
{
public CheckBoxListViewItemSource(String text)
{
m_text = text;
}
public bool IsChecked
{
get { return m_checked; }
set
{
if (m_checked == value) return;
m_checked = value;
RaisePropertyChanged("IsChecked");
}
}
public String Text
{
get { return m_text; }
set
{
if (m_text == value) return;
m_text = value;
RaisePropertyChanged("Text");
}
}
public override string ToString()
{
return Text;
}
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string propName)
{
PropertyChangedEventHandler eh = PropertyChanged;
if (eh != null)
{
eh(this, new PropertyChangedEventArgs(propName));
}
}
private bool m_checked;
private String m_text;
}
ListView中复选框的可见性绑定到ListViewItem的IsChecked值。转换器是一个简单的bool to visibility转换器:
public class BoolToVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter,
CultureInfo culture)
{
if (value is Boolean)
{
return ((bool)value) ? Visibility.Visible : Visibility.Collapsed;
}
return value;
}
public object ConvertBack(object value, Type targetType, object parameter,
CultureInfo culture)
{
throw new NotImplementedException();
}
}
在ListView后面的代码我有:
void listView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
foreach (var item in e.RemovedItems)
{
CheckBoxListViewItemSource source = item as CheckBoxListViewItemSource;
source.IsChecked = false;
}
foreach (var item in e.AddedItems)
{
CheckBoxListViewItemSource source = item as CheckBoxListViewItemSource;
source.IsChecked = true;
}
}
复选框可见性的绑定对我不起作用。默认的IsChecked值为false,因此列表显示时没有复选框。如果我选择了一个项目,则不会出现该复选框。
但是,如果我将IsChecked的默认值设置为true,则所有列表项都会显示一个复选框,如果我选择一个项目然后取消选中它,则复选框会正确消失。
我想要实现的是,所有项目都从没有复选框开始,选择项目显示已选中复选框,取消选择项目会隐藏复选框。
我出错的任何想法?
答案 0 :(得分:1)
手动将第一个GridViewColumn的宽度设置为固定值。似乎ListView将它的宽度设置为零,如果它什么都不包含,并且当复选框开始出现时不会更新宽度。
或者,更改BoolToVisibilityConverter的代码以返回Visibility.Hidden而不是Visibility.Collapsed。
答案 1 :(得分:1)
我知道这已经得到了回答,但我使用以下方法解决了这个问题:
<GridViewColumn Header="MyColumn">
<GridViewColumn.CellTemplate>
<DataTemplate>
<ContentPresenter Content="{Binding MyItem, UpdateSourceTrigger=PropertyChanged}" ContentTemplate="{StaticResource myTemplate}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
在Window中我有一个为MyItem类型定义的DataTemplate:
<Window.Resources>
<DataTemplate DataType="{x:Type myViewModels:MyItemViewModel}" x:Key="myTemplate" >
...template code
</DataTemplate>
</Window.Resources>