如何在自定义控件中获取数据绑定文本块以进行更新?

时间:2012-04-18 16:05:59

标签: c# windows-phone-7 mvvm

设置

所以我有一个课程ComputerItem,旨在存储我需要知道的关于特定计算机的所有内容;这些项目存储在ObservableCollection<ComputerItem>中。然后我有一个自定义控件ComputerControl,它有(除其他外)一些绑定到ComputerItem成员的文本框,这些绑定可以这样提供:

<TextBlock Name="tb_computerName"TextWrapping="Wrap" Text="{Binding ElementName=ComputerControl1, Path=computerName}"/>

并在

背后的代码中
public static DependencyProperty computerNameProperty = DependencyProperty.Register("computerName", typeof(string), typeof(ComputerControl), null);

然后我创建了一个MultiselectList个ComputerControl对象:

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
    <toolkit:MultiselectList x:Name="lb_computers" IsSelectionEnabledChanged="lb_computers_IsSelectionEnabledChanged"> <!--SelectionChanged="lb_computers_SelectionChanged" >-->
        <toolkit:MultiselectList.ItemTemplate>
            <DataTemplate>
               <StackPanel x:Name="sp">
                    <local:ComputerControl computerName="{Binding Name}" MACAddress="{Binding DisplayMAC}" playClicked="playClicked_Handler" editClicked="editClicked_Handler"/>
                </StackPanel>
            </DataTemplate>
        </toolkit:MultiselectList.ItemTemplate>
    </toolkit:MultiselectList>
</Grid>

您可以在ComputerControl定义中看到数据绑定。在后面的代码中,我将ObservableCollection绑定到MultiselectList:

this.lb_computers.ItemsSource = ComputerListMaintainer.GetList();

所有这些(以及我确定我已经忘记包含在这里的一些内容)可以很好地使用代表ObservableCollection中的ComputerItems的ComputerControl来填充MultiselectList。

问题

我的问题是,当底层ComputerItem发生更改时,相应ComputerControl中的TextBlocks不会更新。我在ComputerItem类中实现了INotifyPropertyChanged

public class ComputerItem : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    private string name;

    protected virtual void OnPropertyChanged(string name)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(name));
    }
    public string Name
    {
        get { return name; }
        set { OnPropertyChanged("Name"); name = value; }
    }
}

但这并没有解决问题。我怀疑它与ComputerControl有关,但我不知道从哪里开始寻找;我发现最接近的问题建议INotifyPropertyChanged应该是解决方案,但在这种情况下他们没有使用自定义控件,只是一个自定义类,如果我没记错的话。

我错过了什么?

1 个答案:

答案 0 :(得分:2)

对于初学者来说,你的二传手是不正确的;同时也要研究MvvmLight,因为它为这种管道工作提供了很好的API。

public string Name
{
    get { return name; }
    set 
    { 
        if(value != name)
        {
            name = value;
            OnPropertyChanged("Name"); 
        }
    }
}

<强>更新

您不应该在代码中设置lb_computers.ItemsSource,因为这是一次性操作而不是绑定。最好绑定到ObservableCollection的可观察对象(又名INotifyPropertyChanged)。

此外,我不确定您是否正确声明了依赖属性,因此,您可以在下面找到有关如何定义“可绑定”属性的正确设置。

对于XAML,您的代码架构至关重要,以获得理智的体验。我强烈建议您使用Mvvm模式。我发现MvvmLight和MEFedMVVM是我开发中的重要帮助。这在开始时需要一些工作,但调试未来问题和维护代码会容易得多。

如果这些提示没有帮助,那么我必须看到您的完整代码。

声明可绑定属性

#region ReportName

    public string ReportName
    {
        get { return (string)GetValue(ReportNameProperty); }
        set { SetValue(ReportNameProperty, value); }
    }

    public static readonly DependencyProperty ReportNameProperty = DependencyProperty.Register("ReportName",
        typeof(string), typeof(ExportableGridView), new PropertyMetadata("Report", new PropertyChangedCallback(OnReportNameChanged)));

    public static void OnReportNameChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
    {
        ExportableGridView control = sender as ExportableGridView;
        control.titleTextBlock.Text = e.NewValue as string;
    }

#endregion ReportName