我正在实现一个ComboBox,用户可以使用按钮进行刷新。我试图使之前选择的项目在刷新后如果仍然存在于ComboBox中,则自动重新选择。
MainWindow.xaml:
<ComboBox Canvas.Left="10" Canvas.Top="10" DisplayMemberPath="Name" IsEnabled="{Binding Path=Enabled}" ItemsSource="{Binding Path=Items}" SelectedItem="{Binding Mode=TwoWay, Path=SelectedItem}" Width="379"/>
<Button Content="{x:Static p:Resources.TextRefresh}" Canvas.Right="10" Canvas.Top="10" Click="OnClickButtonRefresh" Width="75"/>
MainWindow.xaml.cs:
public MainWindow()
{
InitializeComponent();
DataContext = m_BrowserInstances = new BrowserInstancesViewModel();
}
private void OnClickButtonRefresh(Object sender, RoutedEventArgs e)
{
m_BrowserInstances.Populate();
}
[已编辑至当前版本] BrowserInstancesViewModel.cs:
public sealed class BrowserInstancesViewModel : ViewModel
{
private Boolean m_Enabled;
public Boolean Enabled
{
get { return m_Enabled; }
}
private BrowserInstance m_SelectedItem;
public BrowserInstance SelectedItem
{
get { return m_SelectedItem; }
set
{
if (m_SelectedItem != value)
{
m_SelectedItem = value;
NotifyPropertyChanged("SelectedItem");
}
}
}
private ObservableCollection<BrowserInstance> m_Items;
public ObservableCollection<BrowserInstance> Items
{
get { return m_Items; }
}
public BrowserInstancesViewModel()
{
Populate();
}
private static Func<BrowserInstance, Boolean> Recover(BrowserInstance selectedItem)
{
return x =>
{
Process currentProcess = x.Process;
Process selectedProcess = selectedItem.Process;
if (currentProcess.Id != selectedProcess.Id)
return false;
if (currentProcess.MainModule.BaseAddress != selectedProcess.MainModule.BaseAddress)
return false;
if (currentProcess.MainWindowTitle != selectedProcess.MainWindowTitle)
return false;
return true;
};
}
public void Populate()
{
BrowserInstance item = m_SelectedItem;
List<BrowserInstance> items = new List<BrowserInstance>();
foreach (Process process in Process.GetProcessesByName("chrome"))
items.Add(new BrowserInstance(process));
if (items.Count > 0)
{
m_Enabled = true;
m_Items = new ObservableCollection<BrowserInstance>(items.OrderBy(x => x.Process.Id));
if (item != null)
m_SelectedItem = m_Items.SingleOrDefault(Recover(item));
if (m_SelectedItem == null)
m_SelectedItem = m_Items[0];
}
else
{
m_Enabled = false;
m_Items = new ObservableCollection<BrowserInstance>();
m_Items.Add(new BrowserInstance());
m_SelectedItem = m_Items[0];
}
NotifyPropertyChanged("Enabled");
NotifyPropertyChanged("Items");
NotifyPropertyChanged("SelectedItem");
}
}
我可以获取之前选中的项,但有时候不行。看起来当需要选择默认值(索引0)时,代码不能正常工作,如果无法恢复先前选择的项目。
System.Diagnostics.Process
Process和System.String Name
...我只需要比较进程,但我找不到一个正确检查两个进程是否相同的方法。 - Tommaso BelluzzoObject.Equals
和Object.GetHashCode
方法。如何执行比较取决于您和您的程序如何定义 BrowserInstance 的相等性。例如,您可以使用Recover
中的逻辑。 - Daniel Hilgarth