Как связать список дочерних объектов в Silverlight MVVM - PullRequest
1 голос
/ 18 мая 2011

В Silverlight, MVVM мне нужно создать окно свойств, но у меня есть только List<AProperty> объект, где AProperty - абстрактный класс с некоторыми дочерними классами.

Я хочу привязать его к элементу управления Silverlight (но к какому?) С некоторыми условиями:

  1. некоторые дочерние свойства должны отображаться в виде текстового поля, некоторые в виде флажка, а некоторые в виде комбинированного списка. Это происходит от динамического типа.
  2. класс AProperty имеет поля PropertyGroup и Name. Порядок должен быть буквенным (PropertyGroup > Name)

Есть идеи или рабочий пример?

Мой код:

    public abstract class AProperty {
        private String _Name;
        private String _Caption;
        private String _PropertyGroup;

        public String Name {
            get { return _Name; }
            set { _Name = value; }
        }

        public String Caption {
            get { return _Caption; }
            set { _Caption = value; }
        }

        public String PropertyGroup {
            get { return _PropertyGroup; }
            set { _PropertyGroup = value; }
        }
    }
    List<AProperty> Properties;

И xaml:

<ListBox ItemsSource="{Binding ... Properties ...}">
  <!-- Here order the items -->
  <ListBox.ItemTemplate>
    <DataTemplate>
      <StackPanel Orientation="Horizontal">
        <TextBlock Width="250"
                    Text="{Binding Path=Caption}" />

        <!-- And here need I a textbox, or a checkbox, or a combobox anyway -->
      </StackPanel>
    </DataTemplate>
  </ListBox.ItemTemplate>
</ListBox>

Я нашел преобразователи значений только для атрибута управления, а не для всего содержимого стековой панели.

Ответы [ 3 ]

1 голос
/ 18 мая 2011

ValueConverter, который упоминает Энди, должен работать. Под вашим текстовым блоком есть ContentPresenter и привязывайте его содержимое.

Content = {Binding, ConverterParameter = {StaticResource NAMEOFCONVERTER}}.

Привязка к свойству пуста, поскольку у вас уже есть объект, который вы хотите использовать в качестве контекста. Затем просто проверьте тип и верните нужный элемент управления. вы можете захотеть создать пользовательские элементы управления, которые являются просто текстовыми блоками и т. д., чтобы вы могли установить привязку там, в противном случае вам придется делать это в коде.

1 голос
/ 18 мая 2011

Вы можете использовать конвертер значений, чтобы проверить тип объекта и вернуть правильный тип элемента управления.

У вас есть пример кода, чтобы я мог привести лучший пример?

0 голосов
/ 19 мая 2011

Спасибо Джесси и Энди, вот решение

Конвертер:

public class PropertyConverter : IValueConverter {
        public object Convert( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture ) {
            Binding ValueBinding = new Binding() {
                Source = value,
                Path = new PropertyPath( "Value" ),
                Mode = BindingMode.TwoWay
            };

            Binding EditableBinding = new Binding() {
                Source = value,
                Path = new PropertyPath( "Editable" ),
                Mode = BindingMode.TwoWay
            };

            if( value is PropertyString ) {
                TextBox tb = new TextBox();
                tb.SetBinding( TextBox.TextProperty, ValueBinding );
                tb.SetBinding( TextBox.IsEnabledProperty, EditableBinding );

                return tb;
            } else if( value is PropertyBoolean ) {
                CheckBox cb = new CheckBox();
                cb.SetBinding( CheckBox.IsCheckedProperty, ValueBinding );
                cb.SetBinding( CheckBox.IsEnabledProperty, EditableBinding );

                return cb;
            } ....

            return null;
        }

        public object ConvertBack( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture ) {
            throw new NotImplementedException();
        }
    }

И код xaml:

...
xmlns:Converters="clr-namespace:MyConverters"
...

<UserControl.Resources>
    <Converters:PropertyConverter x:Key="PropertyInput"/>
</UserControl.Resources>

...

<ListBox ItemsSource="{Binding Path=ItemProperties.GeneralProperties}">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="180" />
                            <ColumnDefinition Width="320" />
                        </Grid.ColumnDefinitions>

                        <TextBlock Text="{Binding Name}" Grid.Column="0" />
                        <ContentPresenter Content="{Binding Converter={StaticResource PropertyInput}}" Grid.Column="1" />
                    </Grid>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>

Два артикула: http://shawnoster.com/blog/post/Dynamic-Icons-in-the-Silverlight-TreeView.aspx http://www.silverlightshow.net/items/Silverlight-2-Getting-to-the-ListBoxItems-in-a-ListBox.aspx

...