【发布时间】:2016-07-12 12:49:09
【问题描述】:
最近几天我遇到了一个问题,我很困惑,希望有人帮助我解决这个问题。
我正在开发一个 WPF 应用程序,它在第一次运行时会提示用户手动将检测到的串行端口分配给任意“通道”,在整个应用程序和以后的界面中用于显示数据等。
其中一个关键特性是,一旦在组合框中分配了一个端口,就不能再在其他组合框中进行选择(使用 ComboBoxItem 类的 .IsEnabled 属性)。
我遇到的问题是,虽然最初一切正常 - 每个组合框都已设置,打开下一个会看到之前的选择变灰 - 如果我尝试返回组合框,我已经之前设置它显示一个空的下拉列表。看起来下拉菜单仍处于活动状态,但包含项目的窗口的大小未正确调整。
屏幕截图:
Items are successfully disabled in subsequent combo boxes
Returning to an already selected box results in a blank drop down (blue circle)
这是组合框的 XAML 代码:
<StackPanel Grid.Column="1" Name="ComboPanel" Margin="5, 20, 5, 5">
<ComboBox Margin="0, 5, 0, 0" Width="100" Height="25" Name="cboxChannel0" IsSynchronizedWithCurrentItem="false" ItemsSource="{Binding portCollectionItems, UpdateSourceTrigger=PropertyChanged}" SelectedIndex="0" DropDownOpened="CboxChannel0_DropDownOpened" DropDownClosed="CboxChannel0_DropDownClosed" />
<ComboBox Margin="0, 5, 0, 0" Width="100" Height="25" Name="cboxChannel1" IsSynchronizedWithCurrentItem="false" ItemsSource="{Binding portCollectionItems, UpdateSourceTrigger=PropertyChanged}" SelectedIndex="0" DropDownOpened="CboxChannel0_DropDownOpened" DropDownClosed="CboxChannel0_DropDownClosed" />
<ComboBox Margin="0, 5, 0, 0" Width="100" Height="25" Name="cboxChannel2" IsSynchronizedWithCurrentItem="false" ItemsSource="{Binding portCollectionItems, UpdateSourceTrigger=PropertyChanged}" SelectedIndex="0" DropDownOpened="CboxChannel0_DropDownOpened" DropDownClosed="CboxChannel0_DropDownClosed" />
<ComboBox Margin="0, 5, 0, 0" Width="100" Height="25" Name="cboxChannel3" IsSynchronizedWithCurrentItem="false" ItemsSource="{Binding portCollectionItems, UpdateSourceTrigger=PropertyChanged}" SelectedIndex="0" DropDownOpened="CboxChannel0_DropDownOpened" DropDownClosed="CboxChannel0_DropDownClosed" />
<ComboBox Margin="0, 5, 0, 0" Width="100" Height="25" Name="cboxChannel4" IsSynchronizedWithCurrentItem="false" ItemsSource="{Binding portCollectionItems, UpdateSourceTrigger=PropertyChanged}" SelectedIndex="0" DropDownOpened="CboxChannel0_DropDownOpened" DropDownClosed="CboxChannel0_DropDownClosed" />
<ComboBox Margin="0, 5, 0, 0" Width="100" Height="25" Name="cboxChannel5" IsSynchronizedWithCurrentItem="false" ItemsSource="{Binding portCollectionItems, UpdateSourceTrigger=PropertyChanged}" SelectedIndex="0" DropDownOpened="CboxChannel0_DropDownOpened" DropDownClosed="CboxChannel0_DropDownClosed" />
<ComboBox Margin="0, 5, 0, 0" Width="100" Height="25" Name="cboxChannel6" IsSynchronizedWithCurrentItem="false" ItemsSource="{Binding portCollectionItems, UpdateSourceTrigger=PropertyChanged}" SelectedIndex="0" DropDownOpened="CboxChannel0_DropDownOpened" DropDownClosed="CboxChannel0_DropDownClosed" />
<ComboBox Margin="0, 5, 0, 0" Width="100" Height="25" Name="cboxChannel7" IsSynchronizedWithCurrentItem="false" ItemsSource="{Binding portCollectionItems, UpdateSourceTrigger=PropertyChanged}" SelectedIndex="0" DropDownOpened="CboxChannel0_DropDownOpened" DropDownClosed="CboxChannel0_DropDownClosed" />
<ComboBox Margin="0, 5, 0, 0" Width="100" Height="25" Name="cboxChannel8" IsSynchronizedWithCurrentItem="false" ItemsSource="{Binding portCollectionItems, UpdateSourceTrigger=PropertyChanged}" SelectedIndex="0" DropDownOpened="CboxChannel0_DropDownOpened" DropDownClosed="CboxChannel0_DropDownClosed" />
<ComboBox Margin="0, 5, 0, 0" Width="100" Height="25" Name="cboxChannel9" IsSynchronizedWithCurrentItem="false" ItemsSource="{Binding portCollectionItems, UpdateSourceTrigger=PropertyChanged}" SelectedIndex="0" DropDownOpened="CboxChannel0_DropDownOpened" DropDownClosed="CboxChannel0_DropDownClosed" />
<ComboBox Margin="0, 5, 0, 0" Width="100" Height="25" Name="cboxChannel10" IsSynchronizedWithCurrentItem="false" ItemsSource="{Binding portCollectionItems, UpdateSourceTrigger=PropertyChanged}" SelectedIndex="0" DropDownOpened="CboxChannel0_DropDownOpened" DropDownClosed="CboxChannel0_DropDownClosed" />
<ComboBox Margin="0, 5, 0, 0" Width="100" Height="25" Name="cboxChannel11" IsSynchronizedWithCurrentItem="false" ItemsSource="{Binding portCollectionItems, UpdateSourceTrigger=PropertyChanged}" SelectedIndex="0" DropDownOpened="CboxChannel0_DropDownOpened" DropDownClosed="CboxChannel0_DropDownClosed" />
</StackPanel>
这是与盒子相关的背后代码sn-ps:
public partial class PortWindow : Window, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public ObservableCollection<ComboBoxItem> portCollectionItems { get; set; }
public ComboBoxItem selectedItem;
public bool serialPortsSet { get; set; }
public ComboBoxItem SelectedItem
{
get { return selectedItem; }
set
{
if (selectedItem == value)
return;
selectedItem = value;
OnPropertyChanged("IsEnabled");
}
}
public PortWindow()
{
InitializeComponent();
DataContext = this;
serialPortsSet = false;
portCollectionItems = new ObservableCollection<ComboBoxItem>();
for (int i = 0; i < ActiveSerialPorts.DetectedPorts.Count(); i++)
{
if (i == 0)
{
portCollectionItems.Add(new ComboBoxItem { Content = "<-Select->" });
}
portCollectionItems.Add(new ComboBoxItem { Content = ActiveSerialPorts.DetectedPorts[i] }); // Populates collection with a list of serial port names from another class
}
}
void CboxChannel0_DropDownOpened(object sender, EventArgs e)
{
ComboBox comboBox = sender as ComboBox;
string selectedString = comboBox.SelectionBoxItem as string;
selectedItem = comboBox.SelectedItem as ComboBoxItem;
foreach (ComboBoxItem portItems in portCollectionItems)
{
if (portItems.Content == selectedItem.Content)
{
portItems.IsEnabled = true; //re-enables the previously disabled selection in case the assigned port needs changing
}
}
}
void CboxChannel0_DropDownClosed(object sender, EventArgs e)
{
ComboBox comboBox = sender as ComboBox;
selectedItem = comboBox.SelectedItem as ComboBoxItem;
string itemString = selectedItem.Content.ToString();
if (!itemString.Contains("<-Select->"))
{
foreach (ComboBoxItem portItems in portCollectionItems)
{
if (portItems.Content == selectedItem.Content)
{
portItems.IsEnabled = false; // disables the selected item in the observable collection
return;
}
}
}
}
protected void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
我倾向于相信在绑定方面我缺少一些小而重要的东西。我最初认为是更改共享集合中的属性导致了问题,但是在抑制处理程序中的所有代码并运行它之后,问题仍然存在。
任何帮助将不胜感激!
【问题讨论】:
-
你不应该有 UI 元素的集合,除非你写了一个自定义控件。