简体   繁体   English

数据绑定和样式问题[WP7]

[英]Problem with DataBinding and style [WP7]

I have been trying to bind listbox with an observableConnection in Xaml on WP7 with no luck. 我一直在尝试用WP7上的Xaml中的observableConnection绑定列表框,但是没有运气。 All I want to do is to make listbox to show an instance of my class that inherits from ObservableConnection and apply some style on listbox. 我要做的就是使列表框显示从ObservableConnection继承的类的实例,并在列表框上应用某种样式。 I can do this from code like 我可以从这样的代码中做到这一点

public Storage.Categories tmp;
...
tmp = new Storage.Categories();
listBox1.ItemsSource = tmp;

but how to apply style on that? 但是如何在其上应用样式? Here is code: 这是代码:

<ListBox Height="497"
         HorizontalAlignment="Left"
         Margin="0,104,0,0"
         Name="listBox1"
         VerticalAlignment="Top"
         Width="450">


namespace Genesa.Storage
{
    public class Categories : ObservableCollection<Category>
    {
        public void LoadCategories()
        {
            // deserialize obiect
        }

        public void SaveCategories()
        {
            // serialize obiect
        }

        public Categories() : base()
        {
            LoadCategories();
        }
    }

    public class Category
    {
        public Category() { }
        public String name { get; set; }
        public String description { get; set; }

        public Category(String _name, String _description)
        {
            name = _name;
            description = _description;
        }

        public override string ToString()
        {
            return String.Format("{0} - {1}", name, description);
        }
    }
}

You're going to want to use a DataTemplate. 您将要使用DataTemplate。 A data template let's you structure the items in your ListBox. 数据模板使您可以构建ListBox中的项目。 For example: 例如:

<ListBox>
    <ListBox.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding name}" />
            <TextBlock Text="{Binding description}" />
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

Also, you might want to reconsider inheriting from ObservableCollection. 另外,您可能需要重新考虑从ObservableCollection继承。 If what you're doing is as simple as it looks above, you probably want to stick to creating a class which contains an ObservableCollection and which implements the INotifiyPropertyChanged interface. 如果您的操作如上所示一样简单,则可能要坚持创建一个包含ObservableCollection并实现INotifiyPropertyChanged接口的类。 This is assuming you're using the MVVM design pattern. 这是假设您正在使用MVVM设计模式。 If you're not, feel free to disregard this suggestion. 如果您不是,请随时忽略此建议。 If you are implementing MVVM, you also want to make the Category class implement the INotifyPropertyChanged interface. 如果要实现MVVM,则还希望使Category类实现INotifyPropertyChanged接口。

As Jared suggests, the most appropriate approach to your solution is to provide an ItemTemplate for the ListBox that defines the structure of each item in the ListBox , which enables you to bind directly to properties on your class, instead of having to override the ToString method. 如贾里德暗示的,最合适的方法来解决方案是提供一种ItemTemplateListBox ,其限定在每个项目的结构ListBox ,以便让您直接绑定到属性上你的类,而不必重写ToString方法。 However, there is a small mistake in Jared's DataTemplate because it can only contain a single item, so you need to wrap the elements in some kind of container, as shown below: 但是,Jared的DataTemplate存在一个小错误,因为它只能包含一个项目,因此您需要将元素包装在某种容器中,如下所示:

<ListBox>
    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel>
                <TextBlock Text="{Binding name}" />
                <TextBlock Text="{Binding description}" />
            </StackPanel>
        </DataTemplate>    
    </ListBox.ItemTemplate>
</ListBox>

You only need to implement the INotifyPropertyChanged on your Category class if the properties can change during the lifetime of that object. 如果属性可以在该对象的生存期内更改,则只需要在Category类上实现INotifyPropertyChanged If the values are constant throughout it's lifetime, then there's no need. 如果这些值在整个生命周期中都是恒定的,则没有必要。

usually the ObservableCollection is member of the ViewModel to which the View binds to. 通常,ObservableCollection是View绑定到的ViewModel的成员。 You don't have to inherit from ObservableCollection and the logic from Categories class can be placed inside ViewModel. 您不必从ObservableCollection继承,可以将Categories类的逻辑放在ViewModel中。

Then you need to set DataContext of Page or other object in hierarchy to be the ViewModel and then you can bind for example ListBox.ItemsSource to ViewModel.ObservableCollection. 然后,需要将Page或层次结构中的其他对象的DataContext设置为ViewModel,然后可以将ListBox.ItemsSource绑定到ViewModel.ObservableCollection。

After that DataTemplate will work in scope of Category (single item in ObservableCollection). 之后,DataTemplate将在Category(ObservableCollection中的单个项目)的范围内工作。

Regarding the logic of loading etc, there is usually one more layer responsible for these operations, which is injected to ViewModel, but if you don't want it, it's just fine. 关于加载等的逻辑,通常有另外一层负责这些操作,将其注入到ViewModel中,但是如果您不想要它,那就很好了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM