BindingCustom控件到List <t> </t>

时间:2013-11-23 18:25:21

标签: c# xaml data-binding datacontext inotifypropertychanged

我有自定义控件 - 联系卡:

<Grid>
    <Grid.Background>
        <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
            <GradientStop Color="#FFD8B8EA"/>
            <GradientStop Color="White" Offset="1"/>
        </LinearGradientBrush>
    </Grid.Background>
    <Grid.ColumnDefinitions>
        <ColumnDefinition/>
        <ColumnDefinition/>
    </Grid.ColumnDefinitions>
    <Image Source="images.jpg" />
    <StackPanel Grid.Column="1">
        <TextBlock Text="{Binding Path=name}" Foreground="Black" FontSize="20" />
        <TextBlock Text="{Binding Path=surname}" Foreground="Black" FontSize="20" />
    </StackPanel>
</Grid>

一个容纳4张卡片的容器(也是一个自定义用户控件):

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition/>
        <RowDefinition/>
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition/>
        <ColumnDefinition/>
    </Grid.ColumnDefinitions>
    <StackPanel x:Name="FirstItem" Grid.Column="0" Grid.Row="0"/>
    <StackPanel x:Name="SecondItem" Grid.Column="0" Grid.Row="1"/>
    <StackPanel x:Name="ThirdItem" Grid.Column="1" Grid.Row="0"/>
    <StackPanel x:Name="FourthItem" Grid.Column="1" Grid.Row="1"/>
</Grid>

这是我的对象类:

class FullObject
{
    public string UpdateTime { get; set; }
    public List<Contact> contacts { get; set; }
    public List<Region> regions { get; set; }
}

我遇到的问题是列表

FullObject数据来自JSON格式的服务,所以我这样做:

FullObjectt = JsonConvert.DeserializeObject<FullObject>(result);

用我这样的卡填充我的FlipView:

FourItems FI = new FourItems();
        for (int i = 0; i < 4; i++)
        {
            ContactCard CC = new ContactCard();
            CC.DataContext = FullObjects.contacts[i];
            if (i == 0)
            {
                FI.FirstItem.Children.Add(CC);
            }
            else if (i == 1)
            {
                FI.SecondItem.Children.Add(CC);
            }
            else if (i == 2)
            {
                FI.ThirdItem.Children.Add(CC);
            }
            else
            {
                FI.FourthItem.Children.Add(CC);
                FlipView.Items.Add(FI);
            }
        }

看起来像这样:

enter image description here

当我收到通知时,某些联系人数据已更改,我从服务器获得一个只更改了联系人的列表。因此,我将在当前加载的FullObject中找到已更改的联系人,并将其替换为新的:

让我们假设第一个联系人名称已更改

I will do this:

Contact new = JsonConvert.DeserializeObject<Contact>(result);
FullObjectt.contacts[0]=new;

但是我的卡数据在重置数据上下文之前不会改变。当我这样做时,有没有办法让ContactCard更新数据?:

Contact new = JsonConvert.DeserializeObject<Contact>(result);
FullObjectt.contacts[0]=new;

我试图将List更改为ObservableCollection,但失败了,有人可以指导我吗?

编辑:

我已将FullObject类中的List更改为ObservableCollection:

class FullObject : INotifyCollectionChanged 
{
    public string spTimestamp { get; set; }
    public ObservableCollection<Contact> contacts { get; set; }
    public string scTimestamp { get; set; }
    public List<Region> regions { get; set; }

}

点击按钮,点击i(仅测试):

private void Button_Click(object sender, RoutedEventArgs e)
    {
        FullObjects.contacts[0] = new Contact();
    }

它不会更新卡片......

1 个答案:

答案 0 :(得分:0)

问题在于您创建FourItems视图的方式。在这一行 -

ContactCard CC = new ContactCard();
CC.DataContext = FullObjects.contacts[i];
if (i == 0)
{
   FI.FirstItem.Children.Add(CC);
}

您正在为DataContext明确设置ContactCard,之后将其完全更改为新引用,除非您手动重置DataContext,否则显然不会反映在UI上。

相反,您应该拥有ItemsControl并将其ItemsSource直接绑定到Contacts ObservableCollection。您可以定义ItemTemplate itemsControl来表示一个ContactCard。通过这种方式,您将获得可观察集合的CollectionChanged通知,并且UI将自动更新。

查看以保存四个控件(摆脱stackpanels) -

<Grid>
   <ItemsControl x:Name="ContactItems">
       <ItemsControl.ItemsPanel>
          <ItemsPanelTemplate>
              <UniformGrid Columns="2"/>
          </ItemsPanelTemplate>
       </ItemsControl.ItemsPanel>
       <ItemsControl.ItemTemplate>
           <DataTemplate>
               <local:ContactCard/> <-- Declare local namespace in XAML where 
                                        ContactCard control is declared.
           </DataTemplate>
       </ItemsControl.ItemTemplate>
   </ItemsControl>
</Grid>

填充代码应该是这样的 -

FourItems FI = new FourItems();
FI.ContactItems.ItemsSource = FullObjects.contacts;
FlipView.Items.Add(FI);

现在集合联系人中的任何更新都将由ItemsControl监听,因为它绑定到它并且您的UI将相应地更新。确保联系人为ObservableCollection