Silverlight数据绑定,可观察集合和用户控制

时间:2011-09-14 09:56:20

标签: silverlight data-binding user-controls observablecollection

我遇到了一个我似乎无法解决的数据绑定问题。 (警告:下面的完整代码示例)

我正在开发一个分组控件,可以将不同的项分组到命名组中。我有一个数据模型定义了这个设置,它有一个可观察的组集合,每个组都有一个可观察的项目集合:

  public class GroupingModel
  {
    public ObservableCollection<Group> Groups { get; set; }
    public GroupingModel()
    {
      Groups = new ObservableCollection<Group>();
    }

    public void RegroupItem(Item item)
    {
      var containingGroup = Groups.FirstOrDefault(x => x.Items.Contains(item));
      if (containingGroup == null ||
        item.GroupName == containingGroup.GroupName)
        return;


      containingGroup.Items.Remove(item);

      var newGroup = Groups.FirstOrDefault(x => x.GroupName == item.GroupName);
      if (newGroup == null)
      {
        newGroup = new Group()
        {
          GroupName = item.GroupName
        };
        newGroup.Items.Add(item);
        Groups.Add(newGroup);
      }
      else
      {
        newGroup.Items.Add(item);
      }
    }
  }

  public class Group
  {
    public ObservableCollection<Item> Items { get; set; }
    public string GroupName { get; set; }
    public Group()
    {
      Items = new ObservableCollection<Item>();
    }
  }

  public class Item
  {
    public string GroupName { get; set; }
    public string Title { get; set; }
    public object Content { get; set; }
  }

此数据模型已填充并绑定到DataContext:

  public partial class MainPage : UserControl
  {
    public MainPage()
    {
      InitializeComponent();

      SetupModel();
    }

    private GroupingModel m_model = new GroupingModel();

    private void SetupModel()
    {
      var group = new Group()
                    {
                      GroupName = "Default",
                    };
      for (int i = 0; i < 5; i++)
      {
        Item item = new Item()
                      {
                        Title = "Item " + i,
                        GroupName = "Default",
                        Content = new TextBlock
                                    {
                                      Text = "Hello: " + i,
                                    }
                      };
        group.Items.Add(item);
      }
      m_model.Groups.Add(group);

      DataContext = m_model;
    }

    private void movegroup(object sender, RoutedEventArgs e)
    {
      var firstGroup = m_model.Groups.First();
      var item = firstGroup.Items.FirstOrDefault();
      if (item != null)
      {
        item.GroupName = "NewGroup";
        m_model.RegroupItem(item);
      }
    }
  }

最后,我在XAML中绑定了整个内容,如下所示:

<UserControl x:Class="ObservableCollectionBinding.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:toolkit="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Toolkit" >
  <Grid x:Name="LayoutRoot">
    <Grid.RowDefinitions>
      <RowDefinition Height="Auto" />
      <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>

    <Button Content="Move first to new group" Click="movegroup" />

    <ItemsControl ItemsSource="{Binding Groups}" Grid.Row="1">
      <ItemsControl.ItemTemplate>
        <DataTemplate>
          <StackPanel Orientation="Vertical">
            <TextBlock FontWeight="ExtraBlack" Text="{Binding GroupName}" Margin="0,2,0,2" />

            <ItemsControl ItemsSource="{Binding Items}">
              <ItemsControl.ItemTemplate>
                <DataTemplate>
                  <toolkit:Expander Header="{Binding Title}" Content="{Binding Title}">
                    <!--Content="{Binding Content}"-->
                  </toolkit:Expander>
                </DataTemplate>
              </ItemsControl.ItemTemplate>
            </ItemsControl>
          </StackPanel>
        </DataTemplate>
      </ItemsControl.ItemTemplate>
    </ItemsControl>
  </Grid>
</UserControl>

按下按钮时,我将第一项从默认组移动到新组中,方法是从可观察项目集合中删除,创建新组,在该组中插入项目并将新组添加到可观察的组合集合中。当Expander中的Content属性绑定到Title属性时,这可以正常工作。您可以展开和关闭项目并将它们全部移动到新组。

但是,如果我将其更改为绑定到Content属性(上面注释掉的行,它绑定到在代码隐藏中创建的TextBlock),绑定工作正常(扩展器可以打开和关闭,TextBlock是如果您尝试移动已展开的项目,则应用程序将以 ArgumentException 消息并且消息“值不在预期范围内”。

我是否尝试做一些不受支持的事情(将内容绑定到在代码隐藏中创建的用户控件),我是否设置了错误的绑定或者是其他错误。

注意:我真的希望绑定能够与在codebehind中创建的usercontrol一起工作,因为为我们的特定用户控件创建一个完整的数据绑定模型将是一项非常大的任务。

1 个答案:

答案 0 :(得分:0)

嗯,没有答案真的出现了,我最终跳过数据绑定并在动态网格中手动移动控件。

所以,我认为我会接受这个作为缺乏更好的答案