Jedną z możliwości jest użycie "DataGrid'a", który posiada możliwość edycji, inną wykorzystanie klasy "Adorner" do zaimplementowania edycji listy, można też sterować widocznością elementów w liście za pomocą stylu. Opiszę tę ostatnią drogę.
Zacznijmy więc od deklaracji klasy zawierającej dane wiersza dla "ListBox'a".
public class RowData : ObservableItem { private string _name = string.Empty; public string Name { get { return _name; } set { _name = value; FirePropertyChanged(() => Name); } } public RowData(string name) { Name = name; } }oraz klasa modelu zawierająca kolekcję wierszy.
public class MainWindowViewModel : ObservableItem { private ObservableCollection<RowData> _rows = new ObservableCollection<RowData>(); public ObservableCollection<RowData> Rows { get { return _rows; } set { _rows = value; FirePropertyChanged(() => Rows); } } public MainWindowViewModel() { Rows.Add(new RowData("Łowicz")); Rows.Add(new RowData("Łódź")); Rows.Add(new RowData("Warszawa")); }Dane wyświetlamy za pomocą takiego kodu.
<ListBox SelectionMode="Single" ItemsSource="{Binding Rows}" > <ListBox.ItemTemplate > <DataTemplate> <StackPanel Tag="{Binding}"> <TextBlock Text="{Binding RelativeSource={ RelativeSource FindAncestor,AncestorType={x:Type StackPanel}}, Path=Tag.Name, UpdateSourceTrigger=PropertyChanged }" /> </StackPanel> </DataTemplate> </ListBox.ItemTemplate> </ListBox>Dla każdego wyświetlonego w liście obiektu zdefiniowaliśmy "TextBlock" "zbindowany" do parametru "Name".
Jednak taka prezentacja danych nie umożliwia nam ich modyfikacji.
Aby dane były możliwe do edytowania kontrolka która je wyświetla musi umożliwiać taką możliwość, pasować będzie "TextBox".
Oczywiście kontrolki powinny być wyświetlane naprzemiennie, jak wiersz jest zaznaczony to wyświetlamy "TextBox" w jak nie to "TextBlock".
Widoczność kontrolek obsłużymy za pomocą zdefiniowania stylów.
<Window.Resources> <converters:CompareBoolToVisibilityConverter x:Key ="compareBoolToVisibilityConverter" /> <Style TargetType="{x:Type TextBlock}" x:Key="TextBlockVisibilityBySelection"> <Setter Property="Visibility" Value="{Binding Path=IsSelected, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBoxItem}}, Converter={StaticResource compareBoolToVisibilityConverter}, ConverterParameter=False}" /> </Style> <Style TargetType="{x:Type FrameworkElement}" x:Key="FEVisibilityBySelection"> <Setter Property="Visibility" Value="{Binding Path=IsSelected, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBoxItem}}, Converter={StaticResource compareBoolToVisibilityConverter}, ConverterParameter=True}" /> </Style> </Window.Resources>Tak więc styl "TextBlockVisibilityBySelection" w przypadku zmiany zaznaczenia elementu listy ("IsSelected") zmienia za pomocą "compareBoolToVisibilityConverter" widoczność kontrolki "TextBlock".
Styl "FEVisibilityBySelection" działa analogicznie, z tą różnicą, że do konwertera przekazuje parametr o odwrotnym znaczeniu niż styl "TextBlockVisibilityBySelection".
Konwerter na podstawie flagi "IsSelected" oraz parametru zwraca właściwą wartość dla właściwości "Visibility".
public class CompareBoolToVisibilityConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { return value.ToString() == parameter.ToString() ? Visibility.Visible : Visibility.Collapsed; } public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { return DependencyProperty.UnsetValue; } }Kod "xaml" zmieniamy do postaci.
<ListBox SelectionMode="Single" ItemsSource="{Binding Rows}" > <ListBox.ItemTemplate > <DataTemplate> <StackPanel Tag="{Binding}"> <TextBlock Text="{Binding RelativeSource={ RelativeSource FindAncestor,AncestorType={x:Type StackPanel}}, Path=Tag.Name, UpdateSourceTrigger=PropertyChanged }" Style="{StaticResource TextBlockVisibilityBySelection}" /> <TextBox Text="{Binding RelativeSource={ RelativeSource FindAncestor,AncestorType={x:Type StackPanel}}, Path=Tag.Name, Mode=TwoWay, UpdateSourceTrigger=LostFocus }" Style="{StaticResource FEVisibilityBySelection}" /> </StackPanel> </DataTemplate> </ListBox.ItemTemplate> </ListBox>Efekt działania powyższego programu.
Brak komentarzy:
Prześlij komentarz