【问题标题】:WPF How to make listbox items editable?WPF 如何使列表框项目可编辑?
【发布时间】:2015-05-31 11:33:10
【问题描述】:

我需要将“编辑所选项目”功能添加到我的列表框中。基本上我需要两个中的任何一个:

  • Ctrl+单击列表项,它会神奇地变成一个可编辑的文本框或其他东西,并在编辑时更新数据库中的数据。

  • 按下我的列表框下的“编辑”按钮,打开新的编辑窗口,在那里编辑数据,更新数据库并在编辑窗口关闭时更新列表框。

我遇到的问题:

  • 我想要解决方案的第一个变体,但我真的不知道如何实现。

  • 实现第二个变体我不知道在新窗口中编辑所选项目后如何更新列表框。

这是我的 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>

这就是我的编辑窗口 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>

下面是我如何访问 ListBox 中的 SelectedItem:

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

绑定到列表框的“查询”是ObservableCollection&lt;Query&gt;,其中Query 如下所示:

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

那么,您能帮我实施这两种解决方案吗?

【问题讨论】:

  • 所以你有你选择的项目,你有一个编辑按钮,我不太确定是什么问题......菲利普的回答似乎也很公平。
  • @Noctis 好吧,问题是在构造函数或类似的东西的窗口之间来回传递数据将是一个非常丑陋的解决方案,我想了解如何在那个案子。但无论如何,第一个解决方案(神奇的)会更好:)

标签: c# wpf xaml listbox


【解决方案1】:

你可以用不同的方式解决这个问题。 在我曾经写过的一个项目中,我想双击一个项目打开该项目的编辑窗口。 我选择使用 i.Interaction.Triggers 。具体代码如下:

<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>

现在,每当我双击一个项目时,它都会打开窗口进行编辑。 这是使用 MVVM,所以我不想在我的代码中包含代码。

您必须引用此 dll:system.windows.interactivity.dll,并且您可能想了解一下它们的用法。这里是an article about that

这是完整的列表框代码(至少是相关位):

   <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>

如果您不想双击,或者如果您想删除该项目(使用不同的命令),您还可以获得额外的右键菜单选项

【讨论】:

    【解决方案2】:

    为什么要使用动态?您可以毫无问题地将SelectedItem 转换为Query。拥有它后,您需要做的就是将属性加载到您的编辑窗口并在此处处理编辑。

    您的查询需要实现INotifyPropertyChanged。否则你不会看到ListBox 的变化(因为控件不知道它们)。 https://msdn.microsoft.com/en-us/library/vstudio/ms229614(v=vs.100).aspx

    另外,使用Binding 会更容易。不要忘记将绑定模式设置为TwoWay,这样您的属性就会在您更改它们后得到更新。 http://blog.scottlogic.com/2012/04/20/everything-you-wanted-to-know-about-databinding-in-wpf-silverlight-and-wp7-part-two.html

    为您的窗户。准备一个 Query 属性(例如名为 SelectedQuery),您将选择的实例设置为该属性。然后,您可以使用以下内容绑定您的文本框(在窗口中):Text="{Binding SelectedQuery.Name, Mode="TwoWay"}"。如果您正确地实现了INotifyPropertyChanged 更改窗口中的文本,则应立即在您的ListView 中更改它。

    【讨论】:

    • 您能否详细介绍一下这些绑定?我浏览了您提供的文章,并在我的Query 课程中实现了INotifyPropertyChanged。而且我还在 ListBox.ItemTemplate 绑定中添加了Mode=TwoWay。但是我应该怎么做才能将数据实际传递到新窗口并让它们出现在那里,然后,在单击“保存”按钮后如何更新 ListBox?我应该在哪里添加这些绑定?
    • 是的,现在一切正常!但是如果我想取消编辑,我该怎么办?我的意思是我只想在单击“保存”按钮后进行更改,但只要我在 bew 窗口中编辑数据时就会发生更改。
    • @DenisYakovenko 您可以将原始值保存在某处,并在未单击“保存”按钮时恢复它们,例如。
    猜你喜欢
    • 2010-10-18
    • 2021-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-15
    相关资源
    最近更新 更多