代码之家  ›  专栏  ›  技术社区  ›  jpierson

如何为ItemsControl中的每个项创建覆盖?

  •  1
  • jpierson  · 技术社区  · 15 年前

    Example mock-up

    我目前的想法是尝试只使用XAML,只使用样式、模板,如果必要的话还可以使用附加的属性。其思想是为items控件创建条件DataTemplate,以某种方式用包含my Delete按钮的装饰器包装原始内容。为了在我的项目上有一个状态控件来知道我是否在 删除模式 或者不,我想也许可以创建一个附加的属性,然后可以通过多种方式设置,例如将其绑定到切换按钮或复选框的状态。

    如果有人能帮助说明这些更好的细节,或提供任何更好的建议,我可以如何进行请分享。

    2 回复  |  直到 8 年前
        1
  •  2
  •   John Bowen    15 年前

    通常,您会在ItemContainerStyle中添加类似的内容,以免每次应用此内容时都会弄乱DataTemplate本身。虽然这对于可以修改ListBoxItem模板的ListBox很简单,但很遗憾,基本ItemsControl仅使用ContentPresenter作为其容器,因此不能以相同的方式进行模板化。

    显然,删除逻辑和视觉样式尚未在此处完成,但这将使您开始:

    public class DeleteItemsControl : ItemsControl
    {
        public static readonly DependencyProperty CanDeleteProperty = DependencyProperty.Register(
            "CanDelete",
            typeof(bool),
            typeof(DeleteItemsControl),
            new UIPropertyMetadata(null));
    
        public bool CanDelete
        {
            get { return (bool)GetValue(CanDeleteProperty); }
            set { SetValue(CanDeleteProperty, value); }
        }
    
        public static RoutedCommand DeleteCommand { get; private set; }
    
        static DeleteItemsControl()
        {
            DeleteCommand = new RoutedCommand("DeleteCommand", typeof(DeleteItemsControl));
            DefaultStyleKeyProperty.OverrideMetadata(typeof(DeleteItemsControl), new FrameworkPropertyMetadata(typeof(DeleteItemsControl)));
        }
    
        protected override DependencyObject GetContainerForItemOverride()
        {
            return new DeleteItem();
        }
    
        protected override bool IsItemItsOwnContainerOverride(object item)
        {
            return item is DeleteItem;
        }
    }
    
    public class DeleteItem : ContentControl
    {
        static DeleteItem()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(DeleteItem), new FrameworkPropertyMetadata(typeof(DeleteItem)));
        }
    

    }

    这将在Generic.xaml中进行,或者您可以像在应用程序中应用普通样式一样应用它们:

    <Style TargetType="{x:Type local:DeleteItemsControl}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:DeleteItemsControl}">
                    <Border Background="{TemplateBinding Background}"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}">
                        <ItemsPresenter/>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    
    <Style TargetType="{x:Type local:DeleteItem}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:DeleteItem}">
                    <Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="{TemplateBinding BorderThickness}">
                        <DockPanel>
                            <Button Command="local:DeleteItemsControl.DeleteCommand" Content="X" HorizontalAlignment="Left" VerticalAlignment="Center"
                                Visibility="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type local:DeleteItemsControl}}, Path=CanDelete, Converter={StaticResource BooleanToVisibilityConverter}}"/>
                            <ContentPresenter VerticalAlignment="{TemplateBinding VerticalContentAlignment}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"/>
                        </DockPanel>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    
        2
  •  1
  •   Charlie    15 年前

    DataTemplate 一些绑定。你绝对是在正确的轨道上。

    <Window x:Class="TestWpfApplication.Foods"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:TestWpfApplication"
    xmlns:sys="clr-namespace:System;assembly=mscorlib"
    Title="Foods" ResizeMode="NoResize"
    SizeToContent="WidthAndHeight"
    DataContext="{Binding RelativeSource={RelativeSource Self}}">
    <Window.Resources>
        <local:BoolToVisConverter x:Key="BoolToVisConverter"/>
    </Window.Resources>
    <StackPanel Background="LightGray">
        <ToggleButton Name="EditModeToggle" Content="Edit" HorizontalAlignment="Right" FontFamily="Arial" Padding="4" 
                      Background="#7FA4E6" Foreground="White" BorderBrush="Black" Width="60" Margin="5,5,5,0"/>
        <ListBox ItemsSource="{Binding Items}" 
                 Background="#999" BorderBrush="Black" Margin="5">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <Border CornerRadius="8" Background="#3565BC" Padding="8" 
                            BorderBrush="#333" BorderThickness="1" Margin="2" Width="255">
                        <StackPanel Orientation="Horizontal">
                            <Button Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=RemoveItemCommand}"
                                    Visibility="{Binding ElementName=EditModeToggle, Path=IsChecked, Converter={StaticResource BoolToVisConverter}}">
                                <Button.Content>
                                    <TextBlock Foreground="Red" Text="X" FontWeight="Bold"/>
                                </Button.Content>
                            </Button>
                            <TextBlock Text="{Binding}" Margin="12,0" Foreground="#AAA" VerticalAlignment="Center"
                                       FontSize="14" FontWeight="Bold" FontFamily="Arial"/>
                        </StackPanel>
                    </Border>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </StackPanel>
    

    RoutedCommand :

    public partial class Foods : Window
    {
        private ObservableCollection<String> items = new ObservableCollection<string>();
        private RoutedCommand removeItemCommand = new RoutedCommand();
    
        public Foods()
        {
            InitializeComponent();
    
            items.Add("Ice Cream");
            items.Add("Pizza");
            items.Add("Apple");
    
            CommandBindings.Add(new CommandBinding(removeItemCommand, ExecutedRemoveItem));
        }
    
        public ObservableCollection<String> Items
        {
            get { return items; }
        }
    
        public RoutedCommand RemoveItemCommand
        {
            get { return removeItemCommand; }
        }
    
        private void ExecutedRemoveItem(object sender, ExecutedRoutedEventArgs e)
        {
            DependencyObject container = 
                ItemsControl.ContainerFromElement(e.Source as ItemsControl, e.OriginalSource as DependencyObject);
            ListBoxItem item = container as ListBoxItem;
            items.Remove(item.Content as String);
        }
    }
    

    alt text http://img697.imageshack.us/img697/7033/foodswindow.png