通常您可以使用 CollectionViewSource 进行这样的过滤,但不幸的是,这似乎在这里不起作用,因为 SqlDataSourceEnumerator.GetDataSources() 返回一个 DataTable,而与这些一起使用的集合视图类型似乎并不支持过滤。
正如我相信其他一些答案所暗示的那样,最好的方法可能是将 ObjectDataProvider 替换为您自己的可以适当过滤事物的视图模型类。如果特定服务器有多个实例,这还可以让您执行过滤重复服务器名称等操作。
以下内容可能对您有用,或者至少可以帮助您入门:
public class ViewModel : INotifyPropertyChanged
{
private string _selectedServerName;
private DataTable _dataSources;
public IEnumerable<string> ServerNames
{
get
{
if (_dataSources == null)
{
_dataSources = SqlDataSourceEnumerator.Instance.GetDataSources();
}
return _dataSources.Rows.Cast<DataRow>()
.Where(row => !row.IsNull("ServerName"))
.Select(row => (string)row["ServerName"]).Distinct();
}
}
public string SelectedServerName
{
get { return _selectedServerName; }
set
{
_selectedServerName = value;
NotifyOfPropertyChange("SelectedServerName");
NotifyOfPropertyChange("Instances");
}
}
public IEnumerable<string> Instances
{
get
{
if (_dataSources == null || _selectedServerName == null) return new string[0];
return _dataSources.Rows.Cast<DataRow>()
.Where(row => !row.IsNull("InstanceName") && _selectedServerName.Equals(row["ServerName"]))
.Select(row => (string)row["InstanceName"]);
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyOfPropertyChange(string propertyName)
{
var handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}
然后您需要按如下方式更改您的 XAML(将 ViewModel 上的命名空间声明替换为适合您项目的内容):
<UserControl.Resources>
<WpfApplication1:ViewModel x:Key="ViewModel" />
</UserControl.Resources>
<ComboBox Name="cboServer"
IsEditable="True"
ItemsSource="{Binding ServerNames, Source={StaticResource ViewModel}, Mode=OneWay, IsAsync=True}"
SelectedItem="{Binding SelectedServerName, Source={StaticResource ViewModel}, Mode=TwoWay}"/>
<ComboBox Name="cboInstance"
IsEditable="True"
ItemsSource="{Binding Instances, Source={StaticResource ViewModel}, Mode=OneWay}" />
请注意,您将 cboServer 上的 ItemsSource 和 SelectedItem 属性绑定到 ViewModel 上的属性,并且 SelectedItem 绑定是双向的。这会将选定的服务器名称反馈给 ViewModel,然后 ViewModel 将通知 WPF Instances 属性已更改。 Instances 属性会过滤掉任何与所选服务器名称不匹配的行。