1

当发生输入字段时,如何使 Expander Header 与 ListBox 项一起更改?

* 我只是试图用一张图片发布这个,但是这个网站不允许我发布图片,直到我的声誉超过 10 New] 按钮被单击一次,“John Henry Doe”输入到 Name 字段,“123-4567”输入到 Phone 字段,然后以红色粗体显示“1) As I type here”,箭头指向 Name 和 Phone 字段,然后以红色粗体显示“2)这会改变”,箭头指向列表框中的“John Henry Doe:123-4567”项,然后以红色粗体显示“3)但这不会改变”,箭头指向“新扩展器接头的“联系人”。*

如上图所示(如果我被允许发布图像),当用户在 Name 或 Phone 字段中键入时,ListBox Item 会发生变化。它发生了变化,因为我对 KeyUp 事件执行了 .Refresh() 。但是,Expander 的 Header 应该同时发生变化。据我所知,没有 .Refresh() 。我希望 Expander 的 Header 像 ListBox 的 Item 一样更新,也就是说,在用户键入时。

ListBox 的DataContext 是Contact 类的一个可观察集合。Contact 类有一个名为 ListString 的属性,其 get 方法返回 ListItem() 方法的结果。ListBox 的 ItemTemplate 只是绑定到 ListString 属性。Expander 的 Header 绑定到 ListBox 的 SelectedItem.ListString 并且当前仅在选择不同的 ListBox 项目时更新。我需要在打字时更新它。

下面是代码背后的 XAML 和 C# 代码。在 ListBox 中选择一个条目之前,ListBox 右侧的控件是不可见的。[New] 按钮将一个新项目插入到 ListBox 中并选择它,从而将控件置于右侧以显示并将焦点赋予 Name 字段。当您在名称字段和/或电话字段中键入时,列表框中的相应项目将更新,但扩展器的标题不会更新。在您选择 ListBox 中的另一个项目之前,它不会更新。我希望它在 ListBox 项目更新的同时更新。我怎么做?

<Window x:Class="Binding_List_Expander_04.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Binding List Expander 04"
        Height="350"
        Width="530">
    <Window.Resources>

    </Window.Resources>
    <Grid>
        <StackPanel Orientation="Horizontal" Margin="3">
            <StackPanel Orientation="Vertical" Margin="3">
                <ListBox Name="ContactList"
                         ItemsSource="{Binding}"
                         Width="166"
                         Height="270"
                         Margin="0,0,0,3">
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding Path=ListString}" />
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>
                <Button Name="NewItem" 
                        Content="New"
                        Click="Event_NewContact_Click"
                        Height="23" 
                        Width="75" />
            </StackPanel>
            <StackPanel Orientation="Vertical">
                <StackPanel.Resources>
                    <Style TargetType="ScrollViewer">
                        <Style.Triggers>
                            <DataTrigger Binding="{Binding ElementName=ContactList, Path=SelectedIndex}" Value="-1">
                                <Setter Property="Opacity" Value="0" />
                            </DataTrigger>
                        </Style.Triggers>
                    </Style>
                </StackPanel.Resources>
                <ScrollViewer Height="302">
                    <StackPanel Orientation="Vertical">
                        <Expander Name="ContactExpander">
                            <Expander.HeaderTemplate>
                                <DataTemplate>
                                    <TextBlock Text="{Binding ElementName=ContactList, Path=SelectedItem.ListString}" />
                                </DataTemplate>
                            </Expander.HeaderTemplate>
                            <StackPanel Margin="21,0,0,0"
                                        Orientation="Vertical">
                                <Grid Margin="3"
                                      TextBoxBase.TextChanged="Event_ContactName_TextChanged">
                                    <Grid.RowDefinitions>
                                        <RowDefinition Height="Auto" />
                                        <RowDefinition Height="3" />
                                        <RowDefinition Height="Auto" />
                                    </Grid.RowDefinitions>
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition Width="auto" />
                                        <ColumnDefinition Width="3" />
                                        <ColumnDefinition Width="250" />
                                    </Grid.ColumnDefinitions>
                                    <TextBlock Grid.Row="0"
                                               Grid.Column="0"
                                               Text="Name:" />
                                    <TextBox Grid.Row="0"
                                             Grid.Column="2"
                                             Name="ContactName"
                                             Text="{Binding ElementName=ContactList, Path=SelectedItem.Name, Mode=TwoWay}" />
                                    <TextBlock Grid.Row="2"
                                               Grid.Column="0"
                                               Text="Phone:" />
                                    <TextBox Grid.Row="2"
                                             Grid.Column="2"
                                             Name="ContactPhone"
                                             Text="{Binding ElementName=ContactList, Path=SelectedItem.Phone, Mode=TwoWay}" />
                                </Grid>
                            </StackPanel>
                        </Expander>
                        <Expander Header="&#13;This is a place holder, there will be&#13;many Expanders following this one."
                                  Margin="0,10,0,0">
                            <StackPanel>
                                <TextBlock Text="Data and&#13;Information" FontSize="30" TextAlignment="Center" />
                            </StackPanel>
                        </Expander>
                        <Expander Header="This is another place holder."
                                  Margin="0,10,0,0">
                            <StackPanel>
                                <TextBlock Text="Data and&#13;Information" FontSize="30" TextAlignment="Center" />
                            </StackPanel>
                        </Expander>
                        <Expander Header="This is another place holder."
                                  Margin="0,10,0,0">
                            <StackPanel>
                                <TextBlock Text="Data and&#13;Information" FontSize="30" TextAlignment="Center" />
                            </StackPanel>
                        </Expander>
                    </StackPanel>
                </ScrollViewer>
            </StackPanel>
        </StackPanel>
    </Grid>
</Window>


using System.Windows;
using System.Collections.ObjectModel;
using System.Windows.Threading;
using System.Threading;
using System.Windows.Controls;

namespace Binding_List_Expander_04
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        ObservableCollection<Contact> Contacts = new ObservableCollection<Contact>();

        public MainWindow()
        {
            InitializeComponent();
            ContactList.DataContext = Contacts;
        }

        private void Event_NewContact_Click(object sender, RoutedEventArgs e)
        {
            Contacts.Insert(0, new Contact());
            ContactList.SelectedIndex = 0;
            if (ContactExpander.IsExpanded)
                SetFocus(ContactName);
            else
            {
                ContactExpander.IsExpanded = true;
                SetFocus(ContactName);
            }
        }

        public void SetFocus(UIElement control)
        {
            control.Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, (ThreadStart)delegate { control.Focus(); });
        }

        private void Event_ContactName_TextChanged(object sender, TextChangedEventArgs e)
        {
            var tb = e.Source as TextBox;
            Contact C = ContactList.SelectedItem as Contact;
            if (tb == ContactName)
                C.Name = tb.Text;
            else if (tb == ContactPhone)
                C.Phone = tb.Text;
            ContactList.Items.Refresh();
        }
    }

    public class Contact
    {
        public string Name { get; set; }
        public string Phone { get; set; }
        public string ListString { get { return ListItem(); } } // See comments in ListItem() below.

        public Contact()
        {
            Name = string.Empty;
            Phone = string.Empty;
        }

        private string ListItem()
        {/*
          * This is a simplified version, the actual version is complicated and cannot be templatized.
          * Please, do not suggest templitazing this.  I know this simple version can be templitazed,
          * but the actual version cannot be templatized.  I need to know how to make this work as it
          * currently is.
          */
            if ((Name + Phone).Trim().Length == 0)
                return "<New Contact>";
            else
            {
                string li = Name.Trim();
                if (li.Length != 0 && Phone.Trim().Length != 0) li += ": ";
                return li + Phone.Trim();
            }
        }
    }

}

谢谢你的帮助。

4

0 回答 0