[Silverlight] RIA & ComboBox
От: Spender Канада http://rybkov.livejournal.com
Дата: 11.12.10 19:24
Оценка:
Добрый день, коллеги!

Пытаюсь разабораться с Binding'ом к ComboBox (оригинально на DataForm, но и на Form тоже пойдет)
После поиска решений в Интернете обнаружил, что многие ссылки идут на http://blogs.msdn.com/b/kylemc/archive/2010/06/18/combobox-sample-for-ria-services.aspx

Пытаясь модифицировать этот пример не смог сделать так, чтобы SelectItem у ComboBox'а выбирался в зависимости от Item'а в другом ComboBox'е.

MainPage.xaml
<StackPanel Name="LayoutRoot" Background="White">        
        <!-- Form -->
        <Border>
            <StackPanel>
                <TextBlock Text="Form" Style="{StaticResource FormLabelStyle}" />
                <Grid Name="Form">
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto" />
                        <RowDefinition Height="Auto" />
                        <RowDefinition Height="Auto" />
                        <RowDefinition Height="Auto" />
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto" />
                        <ColumnDefinition />
                    </Grid.ColumnDefinitions>

                    <ex:ComboBoxDataSource Name="ASource" DomainContext="{StaticResource SampleDomainContext}" OperationName="GetAValues" />
                    <ex:ComboBoxDataSource Name="BSource" DomainContext="{StaticResource SampleDomainContext}" OperationName="GetBValues">
                        <ex:ComboBoxDataSource.Parameters>
                            <ex:Parameter ParameterName="a" Value="{Binding SelectedValue, ElementName=AComboBox}" />
                        </ex:ComboBoxDataSource.Parameters>
                    </ex:ComboBoxDataSource>
                    <ex:ComboBoxDataSource Name="CSource" DomainContext="{StaticResource SampleDomainContext}" OperationName="GetCValuesQuery">
                        <ex:ComboBoxDataSource.Parameters>
                            <ex:Parameter ParameterName="b" Value="{Binding SelectedValue, ElementName=BComboBox}" />
                        </ex:ComboBoxDataSource.Parameters>
                    </ex:ComboBoxDataSource>

                    <TextBlock Text="Id" Grid.Row="0" Grid.Column="0" Style="{StaticResource FormLabelStyle}" />
                    <TextBox Grid.Row="0" Grid.Column="1" Text="{Binding Id}" IsReadOnly="True" Style="{StaticResource FormFieldStyle}" />

                    <TextBlock Text="A" Grid.Row="1" Grid.Column="0" Style="{StaticResource FormLabelStyle}" />
                    <ComboBox Name="AComboBox" Grid.Row="1" Grid.Column="1" Style="{StaticResource FormFieldStyle}" 
                              ItemsSource="{Binding Data, ElementName=ASource}"
                              SelectedItem="{Binding A, Mode=TwoWay}"
                              ex:ComboBox.Mode="AsyncEager" />

                    <TextBlock Text="B" Grid.Row="2" Grid.Column="0" Style="{StaticResource FormLabelStyle}" />
                    <ComboBox Name="BComboBox" Grid.Row="2" Grid.Column="1" Style="{StaticResource FormFieldStyle}" 
                              ItemsSource="{Binding Data, ElementName=BSource}"
                              SelectedItem="{Binding B, Mode=TwoWay}"
                              ex:ComboBox.Mode="AsyncEager" />

                    <TextBlock Text="C" Grid.Row="3" Grid.Column="0" Style="{StaticResource FormLabelStyle}" />
                    <ComboBox Name="CComboBox" Grid.Row="3" Grid.Column="1" Style="{StaticResource FormFieldStyle}" 
                              ItemsSource="{Binding Data, ElementName=CSource}"
                              IsEnabled="{Binding IsLoaded}"
                              SelectedItem="{Binding C, Mode=TwoWay}"                             
                              ex:ComboBox.Mode="AsyncEager">
                        <ComboBox.ItemTemplate>
                            <DataTemplate>
                                <StackPanel Orientation="Horizontal">
                                    <TextBlock x:Name="ComboBoxCId" Text="{Binding Id}" Margin="0,0,10,0" />
                                    <TextBlock x:Name="ComboBoxCText" Text="{Binding Name}" />
                                </StackPanel>                                
                            </DataTemplate>
                        </ComboBox.ItemTemplate>
                    </ComboBox>
                </Grid>
            </StackPanel>
        </Border>        
    </StackPanel>


MainPage.xaml.cs

 public partial class MainPage : UserControl
    {
        public MainPage( )
        {
            InitializeComponent( );

            var context = new SampleDomainContext( );
            context.Load( context.GetSampleEntitiesQuery( ), ContextLoad, null );
            
        }

        private void ContextLoad( LoadOperation<SampleEntity> Results )
        {
            if( !Results.HasError )
            {
                Form.DataContext = Results.Entities.FirstOrDefault( );
            }
        }
    }


SampleDomainService.cs


namespace ComboBoxes.Web
{
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    using System.Linq;
    using System.ServiceModel.DomainServices.Hosting;
    using System.ServiceModel.DomainServices.Server;

    [EnableClientAccess]
    public class SampleDomainService: DomainService
    {
        public IEnumerable<SampleEntity> GetSampleEntities( )
        {
            return new[ ]
            {
                new SampleEntity { Id = 1, A = "3", B = "9", C = new EntityC { Id = 27 }, CId = 27 },
            };
        }

        public IEnumerable<string> GetAValues( )
        {
            return new[ ] { 0, 1, 2, 3, 4 }.Select( I => I.ToString( ) );
        }

        [Invoke]
        public IEnumerable<string> GetBValues( string A )
        {
            if( A == null )
            {
                return new string[ 0 ];
            }
            int seed = int.Parse( A );
            if( seed == 0 )
            {
                return new[ ] { "0" };
            }
            return new[ ] { 0, seed, seed * 2, seed * 3, seed * 4 }.Select( I => I.ToString( ) );
        }

        public IEnumerable<EntityC> GetCValues( string B )
        {
            if( B == null )
            {
                return new[ ] { 0, 1 * 2, 2 * 3, 3 * 4 }.Select(
                    I => new EntityC { Id = I } );
            }
            int seed = int.Parse( B );
            if( seed == 0 )
            {
                return new[ ] { new EntityC { Id = 0 } };
            }
            return
                new[ ] { seed, seed * 2, seed * 3, seed * 4 }.Select(
                    I => new EntityC { Id = I } );
        }

        public void UpdateSampleEntity( SampleEntity SampleEntity )
        {
            // do nothing
        }
    }

    [CustomValidation( typeof( Validation ), "ValidateSampleEntity" )]
    public class SampleEntity
    {
        [Key]
        public int Id { get; set; }

        [CustomValidation( typeof( Validation ), "ValidateString" )]
        public string A { get; set; }

        [CustomValidation( typeof( Validation ), "ValidateString" )]
        public string B { get; set; }

        [Include]
        [Association( "Sample_C", "CId", "Id", IsForeignKey = true )]
        [CustomValidation( typeof( Validation ), "ValidateAssociation" )]
        public EntityC C { get; set; }
        public int CId { get; set; }
    }

    public class EntityC
    {
        [Key]
        public int Id { get; set; }

        public string Name
        {
            get { return Id.ToString( ); }
        }

        public override bool Equals( object Obj )
        {
            if( Obj == null )
            {
                return false;
            }

            if( Obj is EntityC )
            {
                return Id == ( (EntityC)Obj ).Id;
            }

            return false;
        }

        public override int GetHashCode( )
        {
            return Id.GetHashCode( );
        }
    }
}


Весь код из примера (только лишь ComboBoxC модифицирован, чтобы отображать Id и Name и, соответственно, добавлено Property Name в EntityC)

В общем проблема в том, почему, когда в ComboBoxB выбирается значение 9, в ComboBoxС не выбирается значение 27 27, но при этом, если выбрать значение 3 в ComboBoxA, то в ComboBoxB выбирается значение 9.

Спасибо.
Re: [Silverlight] RIA & ComboBox
От: Spender Канада http://rybkov.livejournal.com
Дата: 12.12.10 17:23
Оценка:
Как обычно волшебство RSDN работает — сам спросил — сам ответил!

Решение.
Как я и думал, но ссылки на объект SelectedItem и DataContext должны быть одни и теже (иначе как он выберет объект), чтобы добиться этого вместо

var context = new SampleDomainContext( );
context.Load( context.GetSampleEntitiesQuery( ), ContextLoad, null );


надо писать

var context = Resources[ "SampleDomainContext" ] as SampleDomainContext;
if( context != null )
{
   context.Load( context.GetSampleEntitiesQuery( ), ContextLoad, null );
}
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.