4

我有一个用于名字的文本框、一个用于姓氏的文本框和一个用于显示名称的组合框。显示名称是可编辑的,以便用户可以输入他们想要的任何内容。但是,组合框应显示选项列表。

当任一文本框更改时,组合框项目源都会更新。但是,如果用户先前选择了一个值,则 text 属性将被空白。但是如果用户输入了一个值,文本属性仍然存在。如何防止文本值空白?

这是我的代码:

<Window x:Class="MainWindow"
        x:Name="MainApp"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow"
        Height="350"
        Width="525">
    <Grid DataContext="{Binding ElementName=MainApp}">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="auto" />
            <RowDefinition Height="auto" />
            <RowDefinition Height="auto" />
        </Grid.RowDefinitions>
        <TextBox Grid.Row="0"
                 Text="{Binding FirstName}" />
        <TextBox Grid.Row="1"
                 Text="{Binding LastName}" />
        <ComboBox x:Name="MyCb" Grid.Column="1"
                  Grid.Row="2" 
                  Text="{Binding TheName}"
                  ItemsSource="{Binding NameOptions}"
                  IsEditable="True" />
    </Grid>
</Window>

Imports System.ComponentModel

Class MainWindow
    Implements INotifyPropertyChanged

    Public ReadOnly Property NameOptions As List(Of String)
        Get
            Dim result As New List(Of String)
            result.Add(String.Format("{0} {1}", FirstName, LastName))
            result.Add(String.Format("{1}, {0}", FirstName, LastName))
            result.Add(String.Format("{1}, {0} MI", FirstName, LastName))
            Return result
        End Get
    End Property

    Public Property TheName As String

    Private _firstName As String
    Public Property FirstName As String
        Get
            Return _firstName
        End Get
        Set(value As String)
            _firstName = value
            RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("FirstName"))
            RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("NameOptions"))
        End Set
    End Property

    Private _lastname As String
    Public Property LastName As String
        Get
            Return _lastname
        End Get
        Set(value As String)
            _lastname = value
            RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("LastName"))
            RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("NameOptions"))
        End Set
    End Property

    Public Event PropertyChanged(sender As Object, e As PropertyChangedEventArgs) Implements INotifyPropertyChanged.PropertyChanged
End Class
4

2 回答 2

2

在这里查看我的答案: 如何使用 ComboBox 的 Text 属性禁用 ItemsSource 同步

public class ComboBox : System.Windows.Controls.ComboBox
{
    private bool ignore = false;
    protected override void OnSelectionChanged(SelectionChangedEventArgs e)
    {
        if (!ignore)
        {
            base.OnSelectionChanged(e);
        }
    }

    protected override void OnItemsChanged(NotifyCollectionChangedEventArgs e)
    {
        ignore = true;
        try
        {
            base.OnItemsChanged(e);
        }
        finally
        {
            ignore = false;
        }
    }
}
于 2017-04-07T02:49:23.460 回答
0

在更新 NameOptions 之前将 MyCb.SelectedItem 设置为 null。SelectedItem 取代了 Text,并且当 ItemsSource 更新时,它还将尝试更新应该连接到 SelectedItem 的 Text。

public partial class MainWindow : Window, INotifyPropertyChanged
{
    public List<String> NameOptions 
    {
        get 
        {
            MyCb.SelectedItem = null;   // <--- THIS is the solution. just try it!
            List<String> result = new List<String>();    
            result.Add(String.Format("{0} {1}", FirstName, LastName));
            result.Add(String.Format("{1}, {0}", FirstName, LastName));
            result.Add(String.Format("{1}, {0} MI", FirstName, LastName));
            return result;
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public MainWindow()
    {
        InitializeComponent();            
    }

    private String _theName;
    public String TheName
    {
        get { return _theName; }
        set
        {
            _theName = value;
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs("TheName"));
            }
        }
    }

    private String _firstName;
    public String FirstName
    {
        get { return _firstName; }
        set { 
            _firstName = value; 
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs("NameOptions"));
                handler(this, new PropertyChangedEventArgs("FirstName"));
            }
        }
    }

    private String _lastName;
    public String LastName
    {
        get { return _lastName; }
        set { 
            _lastName = value; 
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs("NameOptions"));
                handler(this, new PropertyChangedEventArgs("LastName"));
            }
        }
    }
}
于 2013-04-10T10:21:59.040 回答