我如何知道一个值何时被“重新选择”?在组合框中
本文关键字:重新选择 选择 组合 新选择 何知道 一个 何时 | 更新日期: 2023-09-27 17:52:55
我正在使用ComboBox将文本模板插入到richit控件中(模板的名称在ComboBox的选择列表中)
除了当用户再次在列表中选择相同的值时,这一切都很好。那么SelectionChanged
没有发射。根据事件的名称(SelectionChanged),这是有意义的,但我需要知道该值已被重新选择,以便我可以再次插入它。
是否有一种方法可以知道从组合框中重新选择了一个项目?(或者使用更好的控件?)
我尝试使用DropDownClosed
事件,但即使没有重新选择项目也会触发。(他们打开下拉菜单,然后点击另一个控件)
听起来您使用组合框的方式与正常用法不一致。在插入所选模板的组合框旁边有一个按钮可以吗?我认为这种行为对于熟悉谷歌搜索行为的用户来说效果会更好
我也有同样的问题,我终于找到了答案:
你需要像这样处理SelectionChanged事件和DropDownClosed事件:
在XAML:<ComboBox Name="cmbSelect" SelectionChanged="ComboBox_SelectionChanged" DropDownClosed="ComboBox_DropDownClosed">
<ComboBoxItem>1</ComboBoxItem>
<ComboBoxItem>2</ComboBoxItem>
<ComboBoxItem>3</ComboBoxItem>
</ComboBox>
在c#: private bool handle = true;
private void ComboBox_DropDownClosed(object sender, EventArgs e) {
if(handle)Handle();
handle = true;
}
private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e) {
ComboBox cmb = sender as ComboBox;
handle = !cmb.IsDropDownOpen;
Handle();
}
private void Handle() {
switch (cmbSelect.SelectedItem.ToString().Split(new string[] { ": " }, StringSplitOptions.None).Last())
{
case "1":
//Handle for the first combobox
break;
case "2":
//Handle for the second combobox
break;
case "3":
//Handle for the third combobox
break;
}
}
我能找到的最好的方法是在下拉菜单打开时清除选中的值。这并不理想,因为用户不能保留他们以前的位置作为参考点(对于长列表来说很好)。但这是我能找到的最好的解决办法。
下面是我使用的代码:ctor()
{
myComboBox.DropDownOpened += OnDropDownOpened;
}
private void OnDropDownOpened(object sender, EventArgs e)
{
var comboBox = ((ComboBox)sender);
comboBox.SelectedItem = null;
}
我会使用列表框。用户不需要打开它。相反,他可以立即从列表中选择一个项目。同样,我不会将此函数附加到SelectionChanged
事件,而是附加到MouseDoubleClick
事件。这使得选择和重新选择一个项目很容易。我还会添加一个按钮,它触发相同的功能。双击应该只是这个按钮的一种快捷方式,这个按钮也可以有一个描述性的文字和/或一个图标,这使它更直观。
SelectionChanged
即使在用户使用方向键上下移动时也会触发,但此时不应触发该功能。
您需要提供一些代码来显示您要做的事情。如果一个项目已经被选中,为什么RichEdit
控件的模板还没有被设置好呢?
在处理WPF时,熟悉绑定到视图模型是有帮助的,不仅仅是ItemsSource
,还有SelectedItem
。鉴于您描述的场景,我将使用SelectedItem
到视图模型的绑定,然后将RichEdit
控件的模板绑定到相同的视图模型属性,必要时使用值转换器。这样你就不需要搞砸点击事件之类的东西了。如果视图模型的属性是DependencyProperty
或触发PropertyChanged
事件(参见INotifyPropertyChanged
),则RichEdit
控件的模板应该自动反映下拉框中的选择。
编辑**根据你的评论,我假设你想要的行为是基于组合选择设置文本,但允许用户自定义该文本。但是,如果编辑,他们应该能够重新选择组合值来重置文本。问题是,如果项目已经被选中,那么就没有触发事件来挂钩。解决方案是,如果文本内容发生更改,则应该取消选择任何组合选择(因为组合不再反映文本框的内容)。绑定可以很好地处理这个问题:
为了简单起见,这个示例视图使用了一个TextBox:
<Window x:Class="UISample.UITemplateSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="UITemplateSample" Height="300" Width="300">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<ComboBox ItemsSource="{Binding Path=Templates}" SelectedItem="{Binding Path=SelectedTemplate}" DisplayMemberPath="Name"/>
<TextBox Grid.Row="1" AcceptsReturn="True" TextWrapping="Wrap" Text="{Binding Path=Text}"/>
</Grid>
ViewModel:
class TemplateSampleViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public ObservableCollection<TextTemplate> Templates
{
get;
private set;
}
private TextTemplate _selectedTemplate;
public TextTemplate SelectedTemplate
{
get{ return _selectedTemplate; }
set
{
if ( _selectedTemplate == value )
return;
_selectedTemplate = value;
if (_selectedTemplate != null)
Text = _selectedTemplate.TemplateText;
firePropertyChanged("SelectedTemplate");
}
}
private string _text;
public string Text
{
get { return _text; }
set
{
if ( _text == value )
return;
_text = value;
firePropertyChanged( "Text" );
var matchingTemplate = Templates.FirstOrDefault( t => t.TemplateText == _text );
SelectedTemplate = matchingTemplate;
}
}
public TemplateSampleViewModel(IEnumerable<TextTemplate> templates)
{
Templates = new ObservableCollection<TextTemplate>(templates);
}
private void firePropertyChanged(string propertyName)
{
if ( PropertyChanged != null )
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
和接线:
var viewModel = new TemplateSampleViewModel(new[]
{
new TextTemplate {Name = "First", TemplateText = "This is the first item"},
new TextTemplate {Name = "Second", TemplateText = "This is the second item"},
new TextTemplate {Name = "Third", TemplateText = "This is the third item"},
});
var test = new UITemplateSample {DataContext = viewModel};
test.Show();
这将绑定组合框,然后在选择项目时,文本框将自动更新。当文本框的内容发生变化时,将检查模板,看它是否仍然匹配,如果不匹配,则取消选择组合项。如果条目匹配模板,则自动选择该模板。