带有可选复选框的列表框

时间:2014-03-04 09:21:15

标签: c# wpf xaml

我正试图达到这种情况:

  • 通过DataTemplate
  • 创建一个ListBox,每个单元格包含一个CheckBox和一个TextBox
  • 使列表可选,即。我可以将SelectedItems绑定到我的VM中的集合。
  • 将这些选择链接到复选框的状态(选中,取消选中)。
  • 每当用户在TextBox中键入内容时,将检查并选中复选框,反之亦然,当字符串为空时,将取消选中。

我设法分别得到所有这些标准:

  • 使用此solution绑定到SelectedItems。
  • 将CheckBox.IsChecked绑定到:
    <Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type ListBoxItem}}" Path="IsSelected" Mode="OneWayToSource"/>
  • 将CheckBox.IsChecked绑定到:
    <Binding Path="Text" ElementName="MyTextBox" Converter="{View:EmptyStringToBooleanConverter}" Mode="OneWay"/>

问题是我不能让这两个绑定一起工作。我尝试过像DataTriggers这样的其他解决方案,但它们没有帮助,因为IsSelected不可访问,因为我需要绑定到DataTemplate内部的东西。
我真的试图避免在我的类中添加属性“IsSelected”(由DataTemplate表示)。

请帮忙,只要他们是MVVM-y,我愿意听到疯狂的建议。 谢谢!

2 个答案:

答案 0 :(得分:0)

一般来说:

    默认情况下取消选中
  • 复选框
  • 当您键入字符串“checked”时,将选中该复选框,否则将保持未选中状态
希望它有所帮助。

<强> XAML

<Window x:Class="MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:clr="clr-namespace:WpfApplication1"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Grid.Resources>
            <clr:StringToBooleanConverter x:Key="StringToBooleanConverter"/>
        </Grid.Resources>
        <ListBox ItemsSource="{Binding}">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <CheckBox x:Name="chb" IsChecked="{Binding Text, ElementName=txt, Mode=OneWay, Converter={StaticResource StringToBooleanConverter}}"/>
                        <TextBox x:Name="txt" Text="{Binding Title, UpdateSourceTrigger=PropertyChanged}" Width="150"/>
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </Grid>
</Window>

<强>代码隐藏

Imports System.Collections.ObjectModel

Class MainWindow
    Public Sub New()
        InitializeComponent()
        Me.DataContext = New ObservableCollection(Of DummyClass)(Enumerable.Range(0, 10).Select(Function(a) New DummyClass() With {.Title = "Dummy Title: " & a}))
    End Sub
End Class

Public Class DummyClass
    Property Title As String
End Class

Public Class StringToBooleanConverter
    Implements IValueConverter

    Public Function Convert(value As Object, targetType As Type, parameter As Object, culture As Globalization.CultureInfo) As Object Implements IValueConverter.Convert
        Dim strValue = System.Convert.ToString(value)
        If String.IsNullOrEmpty(strValue) Then
            Return False 'Unchecked
        End If

        If strValue = "checked" Then
            Return True 'checked
        End If

        Return False 'default
    End Function

    Public Function ConvertBack(value As Object, targetType As Type, parameter As Object, culture As Globalization.CultureInfo) As Object Implements IValueConverter.ConvertBack
        Throw New NotImplementedException()
    End Function
End Class

答案 1 :(得分:0)

这是XAML代码:

         <ListBox ItemsSource="{Binding MyList}" SelectionMode="Multiple" Width="200">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <DockPanel Margin="2">
                        <CheckBox DockPanel.Dock="Left" IsChecked="{Binding IsSelected}"/>
                        <TextBox Text="{Binding Text, UpdateSourceTrigger=PropertyChanged}" Background="Transparent"/>
                    </DockPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
            <ListBox.ItemContainerStyle>
                <Style TargetType="{x:Type ListBoxItem}">
                    <Setter Property="IsSelected" Value="{Binding IsSelected}"/>
                </Style>
            </ListBox.ItemContainerStyle>
        </ListBox>

其代码背后:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = this;
        for (int i = 0; i < 100; i++)
        {
            MyList.Add(new ViewModel());
        }
    }
    //MyList Observable Collection
    public ObservableCollection<ViewModel> MyList { get { return _myList; } }
    private ObservableCollection<ViewModel> _myList = new ObservableCollection<ViewModel>();
}

ViewModel类(每个项目):

public class ViewModel : DependencyObject
{
    //Text Dependency Property
    public string Text
    {
        get { return (string)GetValue(TextProperty); }
        set { SetValue(TextProperty, value); }
    }
    public static readonly DependencyProperty TextProperty =
        DependencyProperty.Register("Text", typeof(string), typeof(ViewModel),
        new UIPropertyMetadata(null, (d, e) =>
        {
            ((ViewModel)d).IsSelected = !string.IsNullOrWhiteSpace((string)e.NewValue);
        }));
    //IsSelected Dependency Property
    public bool IsSelected
    {
        get { return (bool)GetValue(IsSelectedProperty); }
        set { SetValue(IsSelectedProperty, value); }
    }
    public static readonly DependencyProperty IsSelectedProperty =
        DependencyProperty.Register("IsSelected", typeof(bool), typeof(ViewModel),
        new UIPropertyMetadata(false, (d, e) =>
        {

        }));
}