(WPF)带有“添加”和“删除”按钮的可编辑列表框

时间:2016-01-27 14:35:51

标签: wpf listbox

可能我错过了一些东西,但我认为应该有一种很好的方式将项目添加到ListBox es,其内容绑定到数据源,而不是在{{{1}附近有单独的按钮1}}从代码中触发ListBox

我想我可以弄清楚如何通过样式在当前选中的按钮附近添加删除按钮。我还不确定哪个参数会触发这个。但是我更关心添加图片中显示的项目 My Awesome Custom Listbox

我还没有进入造型。我所做的是,我采取某种风格并将其拆开,然后创造我真正需要的东西。我甚至不知道在哪里可以看到所有样式技术,比如查看课程参考。

我想知道在add_new_item()ListBox的一角添加一个按钮,但我该如何为它声明一个新的ComboBox,以便我可以分配唯一的功能然后不是一切。

我没有要求提供完整的解决方案,只是暗示要做什么。当我想出来时,我会发一个答案。

一年之后,我已经把这些事情搞清楚了。

3 个答案:

答案 0 :(得分:1)

只需绑定到ObservableCollection并添加值

如果这不是您想要的,请提出更具体的问题

答案 1 :(得分:1)

您必须自己创建按钮并为其分配命令(MVVM)或单击(代码隐藏)。您的列表框itemssource应该是observablecollection,它会在您从列表框中添加或删除项目时通知UI。如果您知道在许多地方想要一个带按钮的列表框,那么您可以从这两个控件中创建一个用户控件。如果你想在lixtbox或combobox中有一个按钮,那么你必须修改这些控件的模板,稍微复杂一点。

答案 2 :(得分:0)

随着时间的推移,我想到了这些东西(UVMCommand是我的ICommand接口实现,我这样使用它更容易):

public class Game : Notifiable {
    public Game() {
        Players = new ObservableCollection<Player>();
        AddNewPlayer = new UVMCommand("AddNewPlayer", p => {
            var pl = new Player() { Text = "New Player", IsSelected = true, IsEdited = true };
            pl.RemoveThis = new UVMCommand("RemoveThis", pp => Players.Remove(pl));
            Players.Add(pl);
        });
    }

    private ObservableCollection<Player> _players;
    public ObservableCollection<Player> Players { get { return _players; } set { _players = value; OnPropertyChanged("Players"); } }

    private UVMCommand _addNewPlayer;
    public UVMCommand AddNewPlayer { get { return _addNewPlayer; } set { _addNewPlayer = value; OnPropertyChanged("AddNewPlayer"); } }
}

public class Player : Notifiable  {
    public Player() {}

    private UVMCommand _removeThis;
    public UVMCommand RemoveThis { get { return _removeThis; } set { _removeThis = value; OnPropertyChanged("RemoveThis"); } }
}

public class Notifiable : INotifyPropertyChanged {
    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string propertyName) {
        // take a copy to prevent thread issues
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

然后在代码隐藏声明中创建用户控件:

public partial class EditableListBox : System.Windows.Controls.ListBox, INotifyPropertyChanged {
    public EditableListBox() {
        InitializeComponent();
        //var s = FindResource("EditableListBoxStyle") as Style;
        //Style = s;
    }

    [Category("Common")]
    public UVMCommand AddItem {
        get { return (UVMCommand)GetValue(AddItemProperty); }
        set {
            SetValue(AddItemProperty, value);
        }
    }

    // Using a DependencyProperty as the backing store for AddItem.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty AddItemProperty =
        DependencyProperty.Register("AddItem", typeof(UVMCommand), typeof(EditableListBox),
            new PropertyMetadata(
                new UVMCommand("Default Command", p => { Debug.WriteLine("EditableListBox.AddITem not defined"); })));

    [Category("Layout")]
    public Orientation Orientation {
        get { return (Orientation)GetValue(OrientationProperty); }
        set { SetValue(OrientationProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Orientation.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty OrientationProperty =
        DependencyProperty.Register("Orientation", typeof(Orientation), typeof(EditableListBox), new PropertyMetadata(Orientation.Vertical));

    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string propertyName) {
        // take a copy to prevent thread issues
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

在XAML中,我使用列表末尾的模板中的添加按钮和项目模板中的删除按钮定义样式:

<ListBox x:Name="listBox" x:Class="MTCQuest.CustomControls.EditableListBox"
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     xmlns:local="clr-namespace:MTCQuest"
     xmlns:zq="clr-namespace:MTCQuest.ViewModel.zQuest;assembly=MTCQuest.ViewModel"
     xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
     xmlns:ccon="clr-namespace:MTCQuest.CustomControls"
     mc:Ignorable="d"
     d:DesignHeight="300" d:DesignWidth="300"
     Style="{DynamicResource EditableListBoxStyle}"
     ItemContainerStyle="{DynamicResource EditableListBoxItemStyle}" d:DataContext="{DynamicResource TestTheme}" ItemsSource="{Binding Questions}">
<ListBox.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="../Resources/StyleRes.xaml"/>
            <ResourceDictionary Source="../Resources/QuestSpacificControlStyles.xaml"/>
        </ResourceDictionary.MergedDictionaries>
        <ccon:BindingExists x:Key="BindingExists"/>
        <ccon:ColorToSolidColorBrushConverter x:Key="ColorToSolidColorBrushConverter"/>
        <zq:Theme x:Key="TestTheme">
            <zq:Theme.Questions>
                <zq:Question IsEdited="True" IsSelected="True" Text="Some Question" Color="#FF2E00FF"/>
                <zq:Question Text="Another Question"/>
            </zq:Theme.Questions>
        </zq:Theme>
        <Style x:Key="EditableListBoxStyle" TargetType="{x:Type ListBox}">
            <Setter Property="Background" Value="Transparent"/>
            <Setter Property="BorderBrush" Value="{StaticResource Pallete.Divider}"/>
            <Setter Property="BorderThickness" Value="1"/>
            <Setter Property="Foreground" Value="{StaticResource Pallete.PrimaryText}"/>
            <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled"/>
            <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
            <Setter Property="ScrollViewer.CanContentScroll" Value="true"/>
            <Setter Property="ScrollViewer.PanningMode" Value="VerticalFirst"/>
            <Setter Property="Stylus.IsFlicksEnabled" Value="True"/>
            <Setter Property="VerticalContentAlignment" Value="Stretch"/>
            <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
            <Setter Property="ItemsPanel" Value="{DynamicResource OrientedItemsPanelTemplate}"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type ListBox}">
                        <ScrollViewer Background="{TemplateBinding Background}"  SnapsToDevicePixels="true" Focusable="false" Padding="{TemplateBinding Padding}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
                            <StackPanel Orientation="{Binding Orientation, ElementName=listBox}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}">
                                <ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                                <ccon:zButton x:Name="AddButton" Command="{Binding AddItem, RelativeSource={RelativeSource TemplatedParent}}"
                                    HorizontalContentAlignment="Left"
                                    Background="Transparent" Foreground="{DynamicResource Pallete.PrimaryText}"
                                    BorderThickness="0">
                                    <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center">
                                        <Rectangle Width="16" Height="16" Margin="5,0"
                                            Fill="{DynamicResource Pallete.Accent}"
                                            OpacityMask="{DynamicResource Icon_PlusSign}"/>
                                        <TextBlock Text="Add" Foreground="{StaticResource Pallete.PrimaryText}"/>
                                    </StackPanel>
                                </ccon:zButton>
                            </StackPanel>
                        </ScrollViewer>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsMouseOver" Value="True">
                                <Setter TargetName="AddButton" Property="Visibility" Value="Visible"/>
                            </Trigger>
                            <DataTrigger Binding="{Binding}" Value="{x:Null}">
                                <Setter Property="IsEnabled" Value="False"/>
                            </DataTrigger>
                            <Trigger Property="IsEnabled" Value="false">
                                <Setter Property="Effect">
                                    <Setter.Value>
                                        <ccon:DesaturateEffect DesaturationFactor=".25"/>
                                    </Setter.Value>
                                </Setter>
                            </Trigger>
                            <MultiTrigger>
                                <MultiTrigger.Conditions>
                                    <Condition Property="IsGrouping" Value="true"/>
                                    <Condition Property="VirtualizingPanel.IsVirtualizingWhenGrouping" Value="false"/>
                                </MultiTrigger.Conditions>
                                <Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
                            </MultiTrigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
        <Style x:Key="EditableListBoxItemStyle" TargetType="{x:Type ListBoxItem}">
            <Setter Property="SnapsToDevicePixels" Value="True"/>
            <Setter Property="Padding" Value="0"/>
            <Setter Property="HorizontalContentAlignment" Value="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource FindAncestor, AncestorLevel=1, AncestorType={x:Type ItemsControl}}}"/>
            <Setter Property="VerticalContentAlignment" Value="{Binding VerticalContentAlignment, RelativeSource={RelativeSource FindAncestor, AncestorLevel=1, AncestorType={x:Type ItemsControl}}}"/>
            <Setter Property="Background" Value="Transparent"/>
            <Setter Property="BorderBrush" Value="Transparent"/>
            <Setter Property="BorderThickness" Value="1"/>
            <Setter Property="Margin" Value="5,0"/>
            <Setter Property="IsSelected" Value="{Binding IsSelected}"/>
            <Setter Property="FocusVisualStyle">
                <Setter.Value>
                    <Style>
                        <Setter Property="Control.Template">
                            <Setter.Value>
                                <ControlTemplate>
                                    <Rectangle Margin="2" SnapsToDevicePixels="True" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" StrokeThickness="1" StrokeDashArray="1 2"/>
                                </ControlTemplate>
                            </Setter.Value>
                        </Setter>
                    </Style>
                </Setter.Value>
            </Setter>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type ListBoxItem}">
                        <Border x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}"
                            Background="{TemplateBinding Background}"
                            Padding="{TemplateBinding Padding}"
                            SnapsToDevicePixels="True">
                            <Grid Height="33" >
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="*"/>
                                    <ColumnDefinition Width="Auto"/>
                                    <ColumnDefinition Width="Auto"/>
                                </Grid.ColumnDefinitions>
                                <TextBox x:Name="TB" Text="{Binding Text}"
                                    VerticalContentAlignment="Center"
                                    HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                    VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                                    Padding="5, 0" BorderThickness="0" GotFocus="TB_GotFocus"
                                    Visibility="Collapsed"/>
                                <Label x:Name="Lb" Content="{Binding Text}"
                                    VerticalContentAlignment="Center"
                                    HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                    VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                                    Padding="5, 0" BorderThickness="0" Margin="2,1,0,0" />
                                <xctk:ColorPicker x:Name="CB" Grid.Column="1" Width="48" Visibility="Collapsed"
                                                  SelectedColor="{Binding Color}"
                                                  ShowRecentColors="True" ShowDropDownButton="False" ShowStandardColors="False"/>
                                <!--<ccon:zButton x:Name="CB" OpacityMask="{DynamicResource Icon_Edit}"
                                              Width="16" Height="16" Panel.ZIndex="19"
                                              Background="{Binding Color, Converter={StaticResource ColorToSolidColorBrushConverter}}" BorderThickness="0"
                                              Visibility="Collapsed" Margin="2" Grid.Column="1"/>-->
                                <ccon:zButton x:Name="DB" OpacityMask="{DynamicResource Icon_MinusSign}"
                                              Command="{Binding RemoveThis}"
                                              Width="16" Height="16" Background="#FFD12929" BorderThickness="0"
                                              Visibility="Collapsed" Margin="2" Grid.Column="2"/>
                            </Grid>
                        </Border>
                        <ControlTemplate.Triggers>
                            <!--<DataTrigger Binding="{Binding IsEdited}" Value="true">
                                <Setter Property="FocusManager.FocusedElement" Value="{Binding ElementName=TB}" />
                            </DataTrigger>-->
                            <MultiTrigger>
                                <MultiTrigger.Conditions>
                                    <Condition Property="IsMouseOver" Value="True"/>
                                </MultiTrigger.Conditions>
                                <Setter Property="Background" TargetName="Bd" Value="#1F26A0DA"/>
                                <Setter Property="BorderBrush" TargetName="Bd" Value="#A826A0DA"/>
                            </MultiTrigger>
                            <MultiTrigger>
                                <MultiTrigger.Conditions>
                                    <Condition Property="Selector.IsSelectionActive" Value="False"/>
                                    <Condition Property="IsSelected" Value="True"/>
                                </MultiTrigger.Conditions>
                                <Setter Property="Background" TargetName="Bd" Value="#3DDADADA"/>
                                <Setter Property="BorderBrush" TargetName="Bd" Value="#FFDADADA"/>
                            </MultiTrigger>
                            <MultiTrigger>
                                <MultiTrigger.Conditions>
                                    <Condition Property="Selector.IsSelectionActive" Value="True"/>
                                    <Condition Property="IsSelected" Value="True"/>
                                </MultiTrigger.Conditions>
                                <Setter Property="Background" TargetName="Bd" Value="#3D26A0DA"/>
                                <Setter Property="BorderBrush" TargetName="Bd" Value="#FF26A0DA"/>
                            </MultiTrigger>
                            <MultiTrigger>
                                <MultiTrigger.Conditions>
                                    <Condition Property="IsMouseOver" Value="True"/>
                                    <Condition Property="IsSelected" Value="True"/>
                                </MultiTrigger.Conditions>
                                <Setter Property="Visibility" TargetName="Lb" Value="Collapsed"/>
                                <Setter Property="Visibility" TargetName="TB" Value="Visible"/>
                                <Setter Property="Visibility" TargetName="DB" Value="Visible"/>
                                <Setter Property="Visibility" TargetName="CB" Value="Visible"/>
                            </MultiTrigger>
                            <DataTrigger Binding="{Binding Color, Converter={StaticResource BindingExists}, FallbackValue=false}" Value="false">
                                <Setter Property="Visibility" TargetName="CB" Value="Collapsed"/>
                            </DataTrigger>
                            <Trigger Property="IsEnabled" Value="False">
                                <Setter Property="TextElement.Foreground" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
        <ItemsPanelTemplate x:Key="OrientedItemsPanelTemplate">
            <VirtualizingStackPanel IsItemsHost="True"
                Orientation="{Binding Orientation, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ccon:EditableListBox}}}"/>
        </ItemsPanelTemplate>
    </ResourceDictionary>
</ListBox.Resources>

现在只是一个:

<ccon:EditableListBox ItemsSource="{Binding Players}" AddItem="{Binding AddNewPlayer}" Orientation="Horizontal" HorizontalContentAlignment="Center" ScrollViewer.VerticalScrollBarVisibility="Disabled"/>

而且地狱啊!我可以垂直或水平。 我不敢相信,当我刚刚学习WPF时,我试图做一些需要知道很多事情并且能够编写它们的东西(命令,模板,触发器,DependencyProperties,INotifyPropertyChanged等等),我有甚至不存在。只是一个yaer ago:)