Is it possible to bind WPF Combobox.SelectedValue to multiple ObjectDataProviders?

喜欢而已 提交于 2019-12-10 10:35:53

问题


Trying to determine if it is possible to bind the SelectedValue of a ComboBox to the inputs of multiple ObjectDataProviders with XAMAL Bindings.

I looked at MultiBinding but that appears to be grouping multiple controls together, not exactly what I'm looking to day.

I'd like to be able to have the ComboBox (locations) change the TextBlock (deviance) which it does AND to call the ObjectDataProvider (CommentProvider) to update the TextBox (locationComments).

This is fairly straightforward in a code-behind but would prefer to not go this route as a learning experience.

XAMAL CODE

<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" />

回答1:


You're on the right track with the MultiBinding. The key is to use a MultiValueCoverter in conjunction with the 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>

Where we were binding to just one thing before, now we are binding it to both ObjectDataProviders. The key factor that lets us do this is the converter:

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
}

Because we just need the same value in both places the CovertBack method is quite simple, however I'm sure you can see that it could be used to parse some complex stuff and pass back different components to different places in the UI.

Using this converter we can also try out a small sample, using two text boxes instead:

<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>

(The Converter in my example exists in the Window's code behind as a separate class) And as you can see testing this out it will update both TextBoxes when the SelectedValue changes.



来源:https://stackoverflow.com/questions/848946/is-it-possible-to-bind-wpf-combobox-selectedvalue-to-multiple-objectdataprovider

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!