绑定ExpanderView做一个viewModel?

时间:2014-02-26 11:15:50

标签: xaml mvvm windows-phone-8 binding

我做了一些ExpanderViews并硬编码了一切。这工作和看起来很好,所以我想清理,只在xaml中编写一个ExpanderView并使用绑定加载其他所有东西。 据我所知,我需要一个关于整个事物的ListBox来使它更具动态性? 到目前为止,这是我的代码:

<ListBox ItemsSource="{Binding ContactDe}">
    <ListBox.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel/>
        </ItemsPanelTemplate>
    </ListBox.ItemsPanel>
    <ListBox.ItemTemplate>
        <DataTemplate>
            <toolkit:ExpanderView Header="{Binding}"
                        ItemsSource="{Binding LocationName}"
                        IsNonExpandable="False">
                <toolkit:ExpanderView.HeaderTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding LocationName}" FontFamily="{StaticResource PhoneFontFamilySemiBold}" LineHeight="{StaticResource LongListSelectorGroupHeaderFontSize}" />
                    </DataTemplate>
                </toolkit:ExpanderView.HeaderTemplate>

                <toolkit:ExpanderView.ExpanderTemplate>
                    <DataTemplate>
                        <TextBlock Text="test" />
                    </DataTemplate>
                </toolkit:ExpanderView.ExpanderTemplate>

                <toolkit:ExpanderView.ItemTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Information}" />
                    </DataTemplate>
                </toolkit:ExpanderView.ItemTemplate>
            </toolkit:ExpanderView>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

ContactViewModel-Class:

public class ContactDeViewModel : INotifyPropertyChanged
{
    private string _locationName;
    public string LocationName
    {
        get
        {
            return _locationName;
        }
        set
        {
            if (value != _locationName)
            {
                _locationName = value;
                NotifyPropertyChanged("LocationName");
            }
        }
    }

    private List<string> _information;
    public List<string> Information
    {
        get
        {
            return _information;
        }
        set
        {
            if (value != _information)
            {
                _information = value;
                NotifyPropertyChanged("Information");
            }
        }
    }
}

这就是我填写ContactViewModel的地方:

this.ContactDe.Add(new ContactDeViewModel()
            {
                LocationName = "Stuttgart",
                Information = new List<string>
                    {
                        "some text"
                    }
            }
            );
            this.ContactDe.Add(new ContactDeViewModel()
            {
                LocationName = "Böblingen",
                Information = new List<string>
                    {
                        "more text"
                    }
            }
            );

我制作了一个SampleViewModel-File,其中包含:

<vm:MainViewModel.ContactDe>
    <vm:ContactDeViewModel LocationName="Location 1" />
    <vm:ContactDeViewModel LocationName="Location 2" />
</vm:MainViewModel.ContactDe>

在预览窗口中,它向我展示了2个带位置1和2的ExpanderViews。但是相同的代码不适用于模拟器或真实设备。我真的不明白哪个Binding-Acces做了什么。如果我能看到一个完整的例子,那对我来说已经很有帮助了。我搜索了许多教程,但大多数只展示了一面,就像一个xaml而没有看到数据的存储方式。

编辑: 现在我编辑了viewModel,因此它不是List<string>而是List<Info>,其中Info仅包含string Text。所以现在我可以说ItemsSource="{Binding Text}"一次只能是1个字符串,对吗?

2 个答案:

答案 0 :(得分:0)

您需要稍微更改绑定

          <toolkit:ExpanderView Header="{Binding LocationName}"
                      ItemsSource="{Binding Information}"
                      IsNonExpandable="False">
                      <toolkit:ExpanderView.HeaderTemplate>
                          <DataTemplate>
                              <TextBlock Text="{Binding}" FontFamily="{StaticResource  honeFontFamilySemiBold}" LineHeight="{StaticResource LongListSelectorGroupHeaderFontSize}" />
                          </DataTemplate>
                      </toolkit:ExpanderView.HeaderTemplate>
                          <toolkit:ExpanderView.ExpanderTemplate>
                              <DataTemplate>
                                  <TextBlock Text="test" />
                               </DataTemplate>
                          </toolkit:ExpanderView.ExpanderTemplate>
                          <toolkit:ExpanderView.ItemTemplate>
                              <DataTemplate>
                                  <TextBlock Text="{Binding}" />
                              </DataTemplate>
                          </toolkit:ExpanderView.ItemTemplate>
                  </toolkit:ExpanderView>

希望有所帮助

答案 1 :(得分:0)

正如评论@ dellywheel的回答所述,您以这种方式设置DataContext

d:DataContext="{d:DesignData SampleData/MainViewModelSampleData.xaml}"

将DataContext设置为仅在设计时使用,因此它在运行时不起作用。要在运行时使用类似方法设置DataContext,您可以尝试这种方式:

<ListBox ItemsSource="{Binding ContactDe}">
    <ListBox.DataContext>
        <vm:MainViewModel/>
    </ListBox.DataContext>
    ........
    ........
</ListBox>

或以这种方式在页面级别设置DataContext

<phone:PhoneApplicationPage>
    <phone:PhoneApplicationPage.DataContext>
        <vm:MainViewModel/>
    </phone:PhoneApplicationPage.DataContext>
    ........
    ........
</phone:PhoneApplicationPage>

另一个建议是,使用ObservableCollection而不是List来使用数据绑定。每当项目添加到集合或从集合中删除时,ObservableCollection都会自动通知视图刷新。