2009-05-11 3 views
2

Попытка определить, можно ли связать SelectedValue ComboBox с входами нескольких ObjectDataProviders с привязками XAMAL.Можно ли связать WPF Combobox.SelectedValue с несколькими ObjectDataProviders?

Я посмотрел на MultiBinding, но, похоже, группирует несколько элементов управления вместе, а не то, что я ищу на день.

Я бы хотел, чтобы ComboBox (местоположения) менял TextBlock (deviance), который он делает И, чтобы вызвать 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" /> 

ответ

3

Вы находитесь на правильном пути с 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 довольно просто, однако я уверен, что вы можете увидеть, что она может быть использована для проанализировать некоторые сложные вещи и передать разные компоненты в разные места в пользовательском интерфейсе.

Используя этот конвертер можно также попробовать небольшой образец, используя два текстовых поля вместо:

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

(Преобразователь в моем примере существует в коде окна позади как отдельный класс) И как вы можете проверить это, он обновит оба TextBox, когда изменяется SelectedValue.

+0

Похоже, что при преобразовании и многосвязности объектдатапровайдеры не срабатывают при изменении выбранного значения. Точка прерывания внутри ConvertBack поражается, но точки останова в моей службе WCF не попадают. – Brian

+0

Я понял свою проблему, если вы не указали исходный тег правильно, он не работает. Представь это. Source = "{StaticResource CommentProvider}" – Brian

+0

Первое, что приходит в голову, это то, что типы должны соответствовать. Несмотря на то, что вы можете в значительной степени использовать любую ценность в любом поле в WPF, некоторые вещи, такие как параметры метода или новое свойство привязки StringFormat, знают тип. Поэтому, если ваш BuKey не является также строкой, которая может вызывать проблемы. Помимо этой возможной причины, он должен работать, и WCF может быть блокирующим здесь. Быстрый способ решить эту проблему - удалить поставщиков данных объектов, а в ConvertBack - вызвать вызовы методов, которые вам нужны. Затем в привязках привязывается к необходимым элементам. – rmoore

Смежные вопросы