如何在 Silverlight MVVM 中绑定子对象列表

发布于 2024-11-08 12:07:46 字数 1548 浏览 0 评论 0原文

在 Silverlight 中,MVVM 我必须创建一个属性窗口,但我只有一个 List 对象,其中 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>

我发现值转换器仅适用于控件属性,而不适用于整个堆栈面板内容。

In Silverlight, MVVM I have to create a property window, but I have just a
List<AProperty> object, where AProperty is an abstract class with some child classes.

I want to bind it to a Silverlight control (but to which one?), with some conditions:

  1. some child-properties must be shown as a textbox, some as a checkbox, and some as a combobox. It comes from the dynamic type.
  2. the AProperty class has a PropertyGroup and a Name field. The order must be alphabetic (PropertyGroup > Name)

Any idea or working example?

My code:

    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;

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

I've found value converters just for a control attribute, not for a whole stackpanel content.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

梦屿孤独相伴 2024-11-15 12:07:46

您可以使用值转换器来检查对象的类型并返回正确的控件类型。

您有任何示例代码以便我可以给出更好的示例吗?

You could use a value converter to check what Type the object is and return the correct control type.

Do you have any sample code so I could give a better example?

提笔落墨 2024-11-15 12:07:46

安迪提到的 ValueConverter 应该可以工作。在您的 Textblock 下面有一个 ContentPresenter,并绑定它的内容。

内容={绑定,ConverterParameter={StaticResource NAMEOFCONVERTER}}。

与属性的绑定为空,因为您已经拥有想要作为上下文的对象。然后只需检查类型并返回您想要的控件即可。您可能想要制作只是文本块等的用户控件,以便您可以在那里设置绑定,否则您将不得不在代码中执行此操作。

The ValueConverter Andy mentions should work. Underneath your Textblock have a ContentPresenter, and bind it's Content.

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

The binding to the property is empty since you already have the object you want as the context. Then just check the type and return the control you want. you may want to make usercontrol's that are just Textblocks, etc. so that you can set the binding there, otherwise you will have to do it in code.

女皇必胜 2024-11-15 12:07:46

谢谢杰西和安迪,这是解决方案

转换器:

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 -Silverlight-TreeView.aspx 中的图标
http://www.silverlightshow.net/items/Silverlight-2-Getting-to-the-ListBoxItems-in-a-ListBox.aspx

Thanks Jesse and Andy, here is the solution

The converter:

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();
        }
    }

And the xaml code:

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

Two artikel:
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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文