首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用ObjectDataProvider延迟绑定WPF ComboBox

如何使用ObjectDataProvider延迟绑定WPF ComboBox
EN

Stack Overflow用户
提问于 2011-12-19 22:05:01
回答 2查看 2K关注 0票数 0

假设我们有一个WPF ComboBox,并希望使用ObjectDataProvider填充它。

代码语言:javascript
复制
<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"
          ItemsSource="{Binding Source={StaticResource InstallDriverProvider}}"
          SelectedItem="{Binding Path=InstallDriverPlugin, Mode=TwoWay}"
          SelectedValue="{Binding Path=InstallDriverPlugin.Name, Mode=TwoWay}"
          SelectedValuePath="id"
        ...

如果GetInstallDrivers()方法调用一些异步返回的服务器方法,比如来自web服务的响应,那么如何填充组合框呢?如何在响应到达后填充组合框?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-12-19 22:20:25

如果您想异步填充组合框,那么使用ObjectDataProvider不是最好的主意。而是使用ViewModel (和MVVM模式),它将combobox数据源作为一个可观察的集合成员属性。然后只需异步获取数据,然后将其发送到UI线程并填充集合。

票数 1
EN

Stack Overflow用户

发布于 2011-12-20 07:08:41

最后,我找到了一个可行的解决方案。也许它不是最好的,但它是有效的,并且维护集中在DataProvider上的一个地方。

我使用了多绑定、MultiValueConverter、DataObjectProvider。首先,我使用INotifyPropertyChanged INotifyPropertyChanging扩展并实现了我的代理类。在那之后,我添加了一个属性来包含结果,然后更改了XAML。

代码语言:javascript
复制
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");
            }
        }
    }

..。然后,我放置了一个通用方法来向服务器发送请求并检索数据

代码语言:javascript
复制
    public List<Transfer.InstallDriverPlugin> GetInstallDrivers()
    {
        RequestContext rq = App.BL.GetInstallPlugins("DATA_PROVIDER_InstallDrivers");
        App.BL.Admin.SetRequestCustomData(rq, new object[] { });
        return InstallDrivers;
    }

..。处理来自服务器的响应的方法

代码语言:javascript
复制
    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中

代码语言:javascript
复制
      <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.最后,多值转换器总是从第二个绑定中获取值,即属性。

代码语言:javascript
复制
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中做一点定制。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8562478

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档