最後我找到了一個可行的解決方案。也許它不是最好的,但它的工作原理和維護重點放在DataProvider上的一個地方。
我用multibinding,MultiValueConverter,DataObjectProvider。 首先我擴展並實施了我的代理類INotifyPropertyChanged,INotifyPropertyChanging。之後,我添加了一個屬性來包含結果,之後改變了XAML。
public class DataProviderProxy : INotifyPropertyChanged, INotifyPropertyChanging
{
private BusinessLayer BL;
private List<Transfer.InstallDriverPlugin> _InstallDrivers = new List<Transfer.InstallDriverPlugin>();
public List<Transfer.InstallDriverPlugin> InstallDrivers
{
get
{
return _InstallDrivers;
}
set
{
if (_InstallDrivers != value)
{
RaisePropertyChanging("InstallDrivers");
_InstallDrivers = value;
RaisePropertyChanged("InstallDrivers");
}
}
}
...然後我放置的常用方法來發送到服務器的請求,並檢索數據
public List<Transfer.InstallDriverPlugin> GetInstallDrivers()
{
RequestContext rq = App.BL.GetInstallPlugins("DATA_PROVIDER_InstallDrivers");
App.BL.Admin.SetRequestCustomData(rq, new object[] { });
return InstallDrivers;
}
...的方法來處理來自服務器的響應
public void ProcessResponse(ResponseContext rc)
{
// Response filter
...
#region Parse result by command
switch (rc.Command)
{
case AgentCommands.GetInstallPlugins:
if (rc.UserToken == "DATA_PROVIDER_InstallDrivers")
{
App.BL.Admin.ConsumeRequest(rc);
InstallDrivers = (List<Transfer.InstallDriverPlugin>)rc.result;
}
break;
...在XAML
<ObjectDataProvider ObjectType="{x:Type provider:DataProviderProxy}" x:Key="BLDataProvider">
</ObjectDataProvider>
<ObjectDataProvider x:Key="InstallDriverProvider"
ObjectInstance="{StaticResource BLDataProvider}"
MethodName="GetInstallDrivers"
IsAsynchronous="True">
</ObjectDataProvider>
<ComboBox Grid.Row="0" Grid.Column="1"
IsEditable="False"
AlternationCount="2"
IsTextSearchEnabled="True"
IsSynchronizedWithCurrentItem="True"
DataContext="{StaticResource BLDataProvider}"
SelectedItem="{Binding Path=InstallDriverPlugin, Mode=TwoWay}"
SelectedValue="{Binding Path=InstallDriverPlugin.Name, Mode=TwoWay}"
SelectedValuePath="id"
Background="LightGreen"
MinHeight="29"
KeyDown="ComboBoxKeyDownHandler"
SelectionChanged="ComboBox_SelectionChanged">
<ComboBox.ItemsSource>
<MultiBinding Converter="{StaticResource InstDrvConverter}">
<Binding Source="{StaticResource InstallDriverProvider}"/>
<Binding Path="InstallDrivers" Source="{StaticResource BLDataProvider}"/>
</MultiBinding>
</ComboBox.ItemsSource>
</ComboBox>
第一個綁定調用metod以檢索異步返回結果並填充屬性的日期。第二個綁定將組合框綁定到屬性InstallDrivers。 最後,多值轉換器始終使用來自第二個綁定(即屬性)的值。
public class InstallDriverConverter : IMultiValueConverter
{
#region IMultiValueConverter Members
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
try
{
return values[1];
}
catch
{
return null;
}
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
#endregion
}
我知道它更復雜,但有幾個優點。幾乎所有內容都在XAML中,管理集中在一起,如果您開發了一個表單並希望填充類似的數據,您可以粘貼代碼並重新使用它,只需在XAML中進行一些自定義即可。
我同意這不是最好的主意,但我想使用ObjectDataProvider,因爲我重用了與數據庫交談的代碼,所以每次調用都幾乎立即返回。當我使用NamedPipes從數據庫更改爲服務器時,必須實施一些請求/響應通信以保持原始代碼不變。看我的竅門。 – Patrik 2011-12-19 15:16:20