【问题标题】:Binding an ExpanderView do a viewModel?绑定一个 ExpanderView 做一个 viewModel?
【发布时间】:2014-03-29 04:17:23
【问题描述】:

我制作了一些 ExpanderView 并对所有内容进行了硬编码。这工作并且看起来不错,所以我想清理并只在 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 类:

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 的 ExpanderView。但相同的代码不适用于模拟器或真实设备。我真的不明白哪个 Binding-Acces 做了什么。如果我能看到一个完整的例子,它已经对我有很大帮助了。我在 Google 上搜索了很多教程,但大多数只显示了一侧,比如 xaml,而没有看到数据是如何存储的。

编辑: 现在我编辑了viewModel,所以它不是List&lt;string&gt;,而是List&lt;Info&gt;,其Info 仅包含string Text。所以现在我可以说 ItemsSource="{Binding Text}" 一次应该只有 1 个字符串,对吧?

【问题讨论】:

  • 我能看到的第一个问题是您将列表(信息)绑定到需要字符串的 TextBlock.Text 属性。
  • 我想做的是将列表中的每个字符串值绑定到自己的 TextBlock。

标签: xaml mvvm windows-phone-8 binding


【解决方案1】:

正如对@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 自动通知视图刷新,每当项目添加到集合或从集合中删除。

【讨论】:

  • 我知道 SampleData 仅用于设计。为了绑定我的 viewModel,我使用了第一个版本,就像你建议的那样:&lt;ListBox ItemsSource="[Binding ContactDe}"&gt;。不知何故,它只是在运行时没有添加任何东西。我将 viewModel 减少到最低限度,只是为了看看它做了什么。我向它添加了 2 个元素(参见主帖中的代码),甚至没有显示静态数据 -> 不知何故无法识别。
  • 好的,发现错误 -.- 在我的 xaml.cs 中,我错过了这一行:DataContext = App.ViewModel; dellywheel 完全正确。我阅读了 10 篇关于扩展视图绑定的教程,但没有人提到这一点。当然这是较低级别的东西,但应该在完整的指南中提及。很遗憾,由于声誉水平,我无法回答。希望大家在这里看到!无论如何,谢谢大家!
  • 我回答的重点不是ItemsSource="[Binding ContactDe}" 部分,你已经知道了。重点在&lt;ListBox.DataContext&gt;...&lt;/ListBox.DataContext&gt; 部分。这是仅从 XAML 设置DataContext 的一种方法,您也可以从上面评论中提到的代码中设置它。
【解决方案2】:

你需要稍微改变你的绑定

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

希望有帮助

【讨论】:

  • 在预览窗口中向我展示了应有的一切,但在模拟器上它不起作用 =/ 现在我看到我在原始帖子中拼写完全错误,将对其进行编辑。还有一些其他的小变化..
  • 检查页面的 DataContext。什么是ContactDe?视图模型列表?
  • ATM 是d:DataContext="{d:DesignData SampleData/MainViewModelSampleData.xaml}",里面有东西,你可以在主帖中看到。它与我在运行时创建的数据具有相同的结构。但不知何故,预览喜欢 sampleData 而模拟器/真实设备不喜欢真实数据 =/
  • d:DataContext 是您的设计时数据(将出现在 Visual Studio 和 Blend 中)。您还需要设置真实的 DataContext 。在 xaml DataContext={Binding YourViewModel} 或后面的代码中,例如 var vm = new MainViewModel(); this.DataContext = vm;
  • 我还没有设置它,测试没有显示任何变化。在其他文件中,我也不使用它oo“我有一个 ViewModels/MainViewModel.cs 和用于真实 viewModels 的单独类。当我创建一个可视项目时,我将它的 ItemSource 设置为某个 viewModel。// 实际上它没有绑定即使我删除了除 locationNames 之外的所有内容。这是一个非常简单的 ViewModel,现在只包含一个 LocationName 字符串,没有其他内容。而且我无法在模拟器/设备上显示 LocationName。
猜你喜欢
  • 1970-01-01
  • 2020-04-03
  • 1970-01-01
  • 2021-04-22
  • 1970-01-01
  • 2013-06-04
  • 2017-05-11
  • 2010-12-31
  • 1970-01-01
相关资源
最近更新 更多