首页 文章

ListView DataTemplate绑定

提问于
浏览
3

我有以下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,则所有列表项都会显示一个复选框,如果我选择一个项目然后取消选中它,则复选框会正确消失 .

我想要实现的是,所有项目都从没有复选框开始,选择一个项目显示一个选中的复选框,并取消选择一个项目隐藏复选框 .

我出错的任何想法?

2 回答

  • 1

    手动将第一个GridViewColumn的宽度设置为固定值 . 似乎ListView将它的宽度设置为零,如果它什么都不包含,并且当复选框开始出现时不会更新宽度 .

    或者,更改BoolToVisibilityConverter的代码以返回Visibility.Hidden而不是Visibility.Collapsed .

  • 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>
    

相关问题