2014-03-04 248 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