简体   繁体   English

WPF如何使列表框项可编辑?

[英]WPF How to make listbox items editable?

I need to add the "edit selected item" functionality to my listbox. 我需要将“编辑所选项目”功能添加到我的列表框中。 Basically I need either of two: 基本上我需要两个中的任何一个:

  • Ctrl+Click on list item and it magically becomes an editable textbox or something and when edited update the data in the database. 按Ctrl +单击列表项,它神奇地成为可编辑的文本框或其他内容,并在编辑时更新数据库中的数据。

  • Press the "Edit" Button under my ListBox, open the new Edit Window, edit the data there, update the database and update the ListBox when the Edit Window is closed. 按下ListBox下的“编辑”按钮,打开新的编辑窗口,在那里编辑数据,更新数据库并在关闭编辑窗口时更新ListBox。

Problems I encountered: 我遇到的问题:

  • I want to have the first variant of the solution but I really don't know how to implement that. 我想拥有解决方案的第一个变体,但我真的不知道如何实现它。

  • Implementing the second variant I didn't get how should I update the ListBox after editing the selected item in a new Window. 实现第二个变体我没有得到如何在新窗口中编辑所选项后更新ListBox。

Here's my XAML of ListBox: 这是我的ListBox的XAML:

<Grid>
    <ListBox x:Name="LstQueries" HorizontalAlignment="Left" Height="228" VerticalAlignment="Top" Width="482" FontFamily="HelveticaNeueCyr" FontSize="16" ItemsSource="{Binding Queries}" MouseDoubleClick="LstQueries_MouseDoubleClick">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel>
                    <Label Content="{Binding Name}" FontWeight="Medium" FontSize="18" FontFamily="Helvetica"/>
                    <TextBlock Text="{Binding Text}" FontSize="16" FontFamily="Helvetica"/>
                </StackPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
    <Button x:Name="BtnEdit" Content="Edit" HorizontalAlignment="Left" Margin="0,228,0,0" VerticalAlignment="Top" Width="482" Height="43" Click="BtnEdit_Click"/>
</Grid>

And here's what my Edit Window XAML like: 这就是我的编辑窗口XAML:

<Grid>
    <TextBox x:Name="TxtName" HorizontalAlignment="Left" Height="23" Margin="99,13,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="183" FontFamily="HelveticaNeueCyr" FontSize="16"/>
    <Label Content="Name:" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" FontFamily="HelveticaNeueCyr" FontSize="16"/>
    <TextBox x:Name="TxtText" HorizontalAlignment="Left" Height="116" Margin="65,45,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="217" FontFamily="HelveticaNeueCyr" FontSize="16"/>
    <Label Content="Text:" HorizontalAlignment="Left" Margin="10,86,0,0" VerticalAlignment="Top" FontFamily="HelveticaNeueCyr" FontSize="16" Height="27" Width="50"/>
    <Button x:Name="BtnSave" Content="Save" HorizontalAlignment="Left" Margin="10,166,0,0" VerticalAlignment="Top" Width="132" Height="33"/>
    <Button x:Name="BtnCancel" Content="Cancel" HorizontalAlignment="Left" Margin="150,166,0,0" VerticalAlignment="Top" Width="132" Height="33" Click="BtnCancel_Click"/>
</Grid>

And here's how I access the SelectedItem in the ListBox: 这是我如何访问ListBox中的SelectedItem:

if (LstQueries.SelectedIndex < 0) return;
dynamic item = LstQueries.SelectedItem as dynamic;
string name = item.Name;
string text = item.Text;

'Queries' that are binded to the listBox is the ObservableCollection<Query> where Query looks like this: 绑定到listBox的“查询”是ObservableCollection<Query> ,其中Query如下所示:

public class Query
{
    public string Id { get; set; }
    public string Name { get; set; }
    public string Text { get; set; }
    public string Autoschool { get; set; }
}

So, could you help me please with implementing either of solutions? 那么,你能帮我解决一下这两种解决方案吗?

You could tackle this in different ways. 你可以用不同的方式解决这个问题。 In a project I wrote once, I wanted to have a double click on an item open up the edit window for that item. 在我写过一次的项目中,我希望双击一个项目,打开该项目的编辑窗口。 I've opted to go with the i.Interaction.Triggers . 我选择使用i.Interaction.Triggers The specific code looks like : 具体代码如下:

<i:Interaction.Triggers>
    <i:EventTrigger EventName="MouseDoubleClick">
        <Command:EventToCommand Command="{Binding EditExercise_Command}" 
                  CommandParameter="{Binding ElementName=LastExercises_ListView
                                            ,Path=SelectedItem}" />
    </i:EventTrigger>
</i:Interaction.Triggers>

Now, whenever I double click an item, it opens the window to edit it. 现在,每当我双击一个项目时,它就会打开窗口进行编辑。 This was using MVVM, so I didn't want to have code in my code behind. 这是使用MVVM,所以我不希望我的代码背后有代码。

You'll have to reference this dll: system.windows.interactivity.dll , and you'll probably want to read a bit about their usage. 你必须引用这个dll: system.windows.interactivity.dll ,你可能想要阅读一下它们的用法。 Here's an article about that . 是一篇关于此的文章

Here's the full listbox code (the relevant bits at least): 这是完整的列表框代码(至少相关位):

   <ListBox x:Name="..."  
              ItemsSource="{Binding FilteredCollection}"
              SelectedItem="{Binding SelectedExercise, UpdateSourceTrigger=PropertyChanged}"
              ...
              >
        <ListBox.ContextMenu>
            <ContextMenu>
                <MenuItem Header ="Edit Exercise"   
                          Command="{Binding EditExercise_Command}" 
                          CommandParameter="{Binding SelectedExercise}"
                />
                <MenuItem Header ="Delete Exercise" 
                          Command="{Binding DeleteExercise_Command}" 
                          CommandParameter="{Binding SelectedExercise}"
                />
            </ContextMenu>
        </ListBox.ContextMenu>

        <i:Interaction.Triggers>
            <i:EventTrigger EventName="MouseDoubleClick">
                <Command:EventToCommand Command="{Binding EditExercise_Command}" 
                                        CommandParameter="{Binding ElementName=LastExercises_ListView
                                                                 , Path=SelectedItem}" 
                />
            </i:EventTrigger>
        </i:Interaction.Triggers>

    </ListBox>

You also get extra right click menu options in case you don't want to double click, or if you want to delete that item (with a different command) 如果您不想双击,或者如果要删除该项目(使用不同的命令),您还可以获得额外的右键单击菜单选项

Why use dynamic? 为何使用动态? You can cast SelectedItem to Query without problem. 您可以毫无问题地将SelectedItemQuery Once you have it, all you need to do is load properties into your Edit Window and handle editing here. 完成后,您只需将属性加载到编辑窗口并在此处理编辑。

Your Query needs to implement INotifyPropertyChanged . 您的查询需要实现INotifyPropertyChanged Otherwise you won't see changes in ListBox (because the control is not aware of them). 否则,您将看不到ListBox更改(因为控件不知道它们)。 https://msdn.microsoft.com/en-us/library/vstudio/ms229614(v=vs.100).aspx https://msdn.microsoft.com/en-us/library/vstudio/ms229614(v=vs.100).aspx

Also, it would be easier to use Binding . 此外,使用Binding会更容易。 Don't forget to set the Binding mode to TwoWay so your properties get updated once you change them. 不要忘记将Binding模式设置为TwoWay以便在更改属性后更新属性。 http://blog.scottlogic.com/2012/04/20/everything-you-wanted-to-know-about-databinding-in-wpf-silverlight-and-wp7-part-two.html http://blog.scottlogic.com/2012/04/20/everything-you-wanted-to-know-about-databinding-in-wpf-silverlight-and-wp7-part-two.html

For your window. 为了你的窗口。 Prepare there single Query property (named SelectedQuery for example) to which you set your selected instance. 准备单个Query属性(例如,名为SelectedQuery),您可以为其设置所选实例。 You can then bind your TextBoxes (in window) using something like this: Text="{Binding SelectedQuery.Name, Mode="TwoWay"}" . 然后,您可以使用以下内容绑定TextBoxes(在窗口中): Text="{Binding SelectedQuery.Name, Mode="TwoWay"}" If you have corretly implemented INotifyPropertyChanged changing text in your window should immediately change it in your ListView . 如果您已正确实现INotifyPropertyChanged ,则在窗口中更改文本应立即在ListView更改它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM