【问题标题】:Is it possible to bind WPF Combobox.SelectedValue to multiple ObjectDataProviders?是否可以将 WPF Combobox.SelectedValue 绑定到多个 ObjectDataProviders?
【发布时间】:2009-05-11 16:35:17
【问题描述】:

尝试确定是否可以使用 XAMAL 绑定将 ComboBox 的 SelectedValue 绑定到多个 ObjectDataProvider 的输入。

我查看了 MultiBinding,但它似乎将多个控件组合在一起,而不是我今天所期待的。

我希望能够让 ComboBox(位置)更改它所做的 TextBlock(偏差)并调用 ObjectDataProvider(CommentProvider)来更新 TextBox(locationComments)。

这在代码隐藏中相当简单,但不希望将这条路线作为一种学习体验。

XAMAL 代码

<Window.Resources>
    <ObjectDataProvider x:Key="LocationProvider"
        ObjectType="{x:Type srv:ServiceClient}"
        IsAsynchronous="True"MethodName="GetAssignedLocations" />
    <ObjectDataProvider
        x:Key="DevianceProvider"
        ObjectType="{x:Type srv:ServiceClient}"
        IsAsynchronous="True" MethodName="GetPercentChange">
        <ObjectDataProvider.MethodParameters>
            <system:String>Location1</system:String>
        </ObjectDataProvider.MethodParameters>
    </ObjectDataProvider>
    <ObjectDataProvider
        x:Key="CommentProvider"
        ObjectType="{x:Type srv:ServiceClient}"
        IsAsynchronous="True"
        MethodName="GetCommentByBusinessUnit">
        <ObjectDataProvider.MethodParameters>
            <system:String>Location1</system:String>
        </ObjectDataProvider.MethodParameters>
    </ObjectDataProvider>
</Window.Resources>

<ComboBox Height="23" HorizontalAlignment="Left" Margin="12,12,0,0" Name="locations"  VerticalAlignment="Top" ItemsSource="{Binding Source={StaticResource LocationProvider}}"
              DisplayMemberPath="BuName" SelectedValuePath="BuKey"
              SelectionChanged="locations_SelectionChanged">
        <ComboBox.SelectedValue>
            <Binding Source="{StaticResource DevianceProvider}"
             Path="MethodParameters[0]"   
                 BindsDirectlyToSource="True" 
                 Mode="OneWayToSource" />
        </ComboBox.SelectedValue>
<TextBlock Name="deviance" Height="23" Margin="0,0,645,17" Width="40" Text="{Binding Source={StaticResource DevianceProvider}}" IsEnabled="False" />

<TextBox Height="23" Margin="0,0,181,17" Name="locationComments" Width="350" />

【问题讨论】:

    标签: wpf wcf data-binding objectdataprovider


    【解决方案1】:

    您在 MultiBinding 的正确轨道上。 关键是将 MultiValueCoverter 与 MultiBinding 结合使用。

    <MultiBinding Converter="{StaticResource Coverter_LocationMultiConverter}"
                  Mode="OneWayToSource">
                    <Binding Source="{StaticResource DevianceProvider}"
                             Path="MethodParameters[0]"
                             BindsDirectlyToSource="True"
                             Mode="OneWayToSource" />
                    <Binding Source="{StaticResource CommentProvider}"
                             Path="MethodParameters[0]"
                             BindsDirectlyToSource="True"
                             Mode="OneWayToSource" />
                </MultiBinding>
    

    之前我们只绑定一个东西,现在我们将它绑定到两个 ObjectDataProviders。让我们这样做的关键因素是转换器:

    public class LocationMultiCoverter : IMultiValueConverter
    {
        #region IMultiValueConverter Members
    
        public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    
        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
        {
            return new object[] { value, value };
        }
    
        #endregion
    }
    

    因为我们只需要在两个地方都使用相同的值,所以 CovertBack 方法非常简单,但是我相信您可以看到它可以用来解析一些复杂的东西并将不同的组件传递回 UI 中的不同位置。

    使用这个转换器,我们也可以尝试一个小示例,使用两个文本框来代替:

    <Window x:Class="Sample.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:Sample"
        Title="Window1"
        Height="300"
        Width="300">
    <Window.Resources>
        <local:LocationMultiCoverter x:Key="Coverter_LocationMultiConverter" />
    </Window.Resources>
    <Grid>
        <StackPanel>
            <TextBlock x:Name="uiDeviance" />
            <TextBlock x:Name="uiComment" />
            <ComboBox x:Name="uiLocations"
                      Height="23"
                      HorizontalAlignment="Left"
                      VerticalAlignment="Top"
                      SelectedValuePath="Content">
                <ComboBoxItem>1</ComboBoxItem>
                <ComboBoxItem>2</ComboBoxItem>
                <ComboBoxItem>3</ComboBoxItem>
                <ComboBoxItem>4</ComboBoxItem>
                <ComboBoxItem>5</ComboBoxItem>
                <ComboBox.SelectedValue>
                    <MultiBinding Converter="{StaticResource Coverter_LocationMultiConverter}"
                                  Mode="OneWayToSource">
                        <Binding ElementName="uiDeviance"
                                 Path="Text"
                                 BindsDirectlyToSource="True" />
                        <Binding ElementName="uiComment"
                                 Path="Text"
                                 BindsDirectlyToSource="True" />
                    </MultiBinding>
                </ComboBox.SelectedValue>
            </ComboBox>
        </StackPanel>
    </Grid>
    

    (我示例中的转换器作为单独的类存在于 Window 的代码中) 正如您所看到的,测试它会在 SelectedValue 更改时更新两个 TextBox。

    【讨论】:

    • 似乎使用转换器和多重绑定,当所选值发生更改时,objectdataproviders 不会触发。 ConvertBack 中的断点被命中,但我的 WCF 服务中的断点没有被命中。
    • 我发现了我的问题,如果你没有正确指定源标签,它就不起作用。想象一下。 Source="{StaticResource CommentProvider}"
    • 首先想到的是类型需要匹配。尽管您可以将几乎任何值塞入 WPF 中的任何字段,但方法参数或新的 StringFormat 绑定属性等某些内容可以识别类型。因此,如果您的 BuKey 也不是可能导致问题的字符串。除了那个可能的原因之外,它应该可以正常工作,而 WCF 可能是这里的障碍。解决此问题的一种快速方法是删除对象数据提供程序,并在 ConvertBack 中调用您需要的方法。然后在绑定中绑定到所需的元素。
    • 很高兴听到这很简单。
    • 我遇到了类似的问题,我不得不将所选项目的多个属性“拆分”为我的视图模型的多个属性,但只有在视图选择更改后(OneWayToSource)。我的自定义转换器需要更多逻辑,否则这个答案非常适合我的用例。这是迄今为止我找到的唯一有效答案,我几乎准备放弃并在后面的代码中实现它,所以谢谢你的这个新技巧!
    猜你喜欢
    • 1970-01-01
    • 2015-06-18
    • 1970-01-01
    • 2011-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-16
    • 2010-10-13
    相关资源
    最近更新 更多