2014-03-04 213 views
1

我试图达到这样的情况:列表框,可选择复选框

  • 有包含CheckBox和一个TextBox每一个小区的列表框,通过DataTemplate中
  • 榜上无名选择,即。我可以将SelectedItems绑定到我的VM中的集合。
  • 将这些选择链接到复选框的状态(选中,未选中)。
  • 每当用户在文本框中键入内容时,复选框将被选中,反之亦然,当字符串为空时,将被取消选中。

我设法让所有的这些指标分析的seperately这样的:

  • 绑定使用这种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。 谢谢!

回答

0

一般:

  • 复选框默认
  • 当你输入字符串未选中“检查”,该复选框将被选中,否则将保持选中

希望它帮助。

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 
+0

我已成功这一点,但它只是我的问题的一半。 – Nadavrbn

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) => 
     { 

     })); 
} 
+0

这对我来说不好,原因有几个。 A)我试图避免在我的对象中称为“IsSelected”的属性。B)我希望CheckBox进行选择的原因不是因为它的背景色很漂亮,而是因为我希望它成为“SelectedItems”的实际部分。 – Nadavrbn

+0

在这种情况下,我的头顶上可以提供帮助。 ListBox(或其他可选控件)中的项目有一个Selector.IsSelected。但我不记得它的正确用法。也许在ListBox.ItemContainerStyle? – Bijan

+0

想过它,但Style不能访问DataTemplate中的TextBox或CheckBox。 – Nadavrbn