C# 如何公开两个ItemsSource列表中的DependencyProperties(不传播)

C# 如何公开两个ItemsSource列表中的DependencyProperties(不传播),c#,wpf,xaml,windows-store-apps,win-universal-app,C#,Wpf,Xaml,Windows Store Apps,Win Universal App,在另一个StackPanel/ItemsSource中获得StackPanel/ItemsSource。内部的一个具有更新的值。无法使其将更新传播到UI 注意:作为已注册的DependencyProperty-它从不更新。作为一个简单的属性{get;set;},它会更新一次,然后再也不会更新。为了传播,它或它们应该是什么 已经查阅了大量的网站、书籍等——他们的例子并没有演示这个用例或工作 这里缺少什么(只是在传播过程中) 注意!(如果不清楚)-这是一个成对的完全运行的示例,用于说明问题。应该清楚

在另一个StackPanel/ItemsSource中获得StackPanel/ItemsSource。内部的一个具有更新的值。无法使其将更新传播到UI

注意:作为已注册的DependencyProperty-它从不更新。作为一个简单的属性{get;set;},它会更新一次,然后再也不会更新。为了传播,它或它们应该是什么

已经查阅了大量的网站、书籍等——他们的例子并没有演示这个用例或工作

这里缺少什么(只是在传播过程中)

注意!(如果不清楚)-这是一个成对的完全运行的示例,用于说明问题。应该清楚的是,这与prod还不太接近,更不用说int或dev了

(更新:似乎是Windows应用商店应用程序特定的问题,因为它在std WPF/etc中工作)

示例DependencyProperty代码(.cs):

使用系统;
使用System.Collections.ObjectModel;
使用System.Threading.Tasks;
使用Windows.UI.Core;
使用Windows.UI.Xaml;
使用Windows.UI.Xaml.Controls;
命名空间TestDependency
{
公共密封部分类主页面:第页
{
私人TopData TopData;
公共主页()
{
this.InitializeComponent();
这个;
}
公共异步void Do(){
topData=新的topData();
this.TopItemsControl.ItemsSource=topData;
var调度程序=调度程序;
var action=新操作(异步()=>
{
while(true)
{
wait dispatcher.RunAsync(CoreDispatcherPriority.Normal,()=>
{
topData[0][1]。值=topData[0][1]。值+1;
});
等待任务。延迟(1000);
}
});
等待任务。运行(操作);
}
}
公共类TopData:ObservableCollection
{
公共TopData()
{
添加(新的中间数据(“ABC”,新的[]{“a1”,“a2”,“a3”});
添加(新的中间数据(“DEF”,新的[]{“d1”,“d2”,“d3”});
添加(新的中间数据(“GHI”,新[]{“g1”,“g2”,“g3”});
}
}
公共类中间数据:ObservableCollection
{
公共字符串名称{get;set;}
公共数据(字符串名称,字符串[]列表)
{
this.Name=Name;
foreach(列表中的变量项)
{
增加(新的底部数据(第0项));
}    
}
}
公共类数据:DependencyObject
{
公共字符串名称{get;set;}
公共静态只读从属属性ValueProperty=
DependencyProperty.Register(“Value”、typeof(double)、typeof(BottomData)、newpropertyMetadata(0d));
公共双重价值
{
获取{return(double)this.GetValue(ValueProperty);}
set{base.SetValue(ValueProperty,value);}
}
公共数据(字符串名称,双值)
{
this.Name=Name;
这个。值=值;
}
}
}
和要匹配的示例xaml代码:

    <Page
    x:Class="TestDependency.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:TestDependency"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <Grid x:Name="TopGrid">

            <Grid.RowDefinitions>
                <RowDefinition Height="5*"/>
                <RowDefinition Height="1*"/>
            </Grid.RowDefinitions>

            <Grid.Resources>
                <DataTemplate x:Key="StackItemTemplate">
                    <StackPanel x:Name="BottomStackPanel"  Orientation="Horizontal">
                        <TextBlock Text="{Binding Path=Name}"/>
                        <TextBlock Text=": "/>
                        <TextBlock Text="{Binding Path=Value}" />
                    </StackPanel>
                </DataTemplate>

                <DataTemplate x:Key="SensorDataTemplate">
                    <StackPanel x:Name="TopStackPanel">
                        <Grid>

                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="20*"/>
                                <ColumnDefinition Width="10*"/>
                            </Grid.ColumnDefinitions>

                            <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="{Binding Path=Name}" Grid.Column="0"/>
                            <StackPanel x:Name="MiddleStackPanel"  Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Center">

                                <ItemsControl x:Name="BottomItemsControl" ItemsSource="{Binding}"  ItemTemplate="{StaticResource StackItemTemplate}">
                                    <ItemsControl.ItemsPanel>
                                        <ItemsPanelTemplate>
                                            <VirtualizingStackPanel Orientation="Vertical"/>
                                        </ItemsPanelTemplate>
                                    </ItemsControl.ItemsPanel>
                                </ItemsControl>

                            </StackPanel>

                        </Grid>
                    </StackPanel>
                </DataTemplate>
            </Grid.Resources>

            <ItemsControl x:Name="TopItemsControl" ItemTemplate="{StaticResource SensorDataTemplate}">
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <VirtualizingStackPanel Orientation="Vertical"/>
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
            </ItemsControl>

        </Grid>
    </Grid>
</Page>

几个亮点:

首先,我不太熟悉Windows Phone开发:我将您的代码导入了WPF应用程序。将
xmlns:local
声明为
“using:TestDependency”
给了我第一拳;我不得不将其替换为
“clr名称空间:TestDependency”

第二,你有:

<ItemsControl x:Name="BottomItemsControl" ItemsSource="{Binding Path=This}" ...

BottomData需要为值实现INotifyPropertyChanged和FirePropertyChanged。这是WPF(更深入地连接DPs)和其他Xaml框架(如Windows.UI.Xaml和(我相信)Silverlight)之间的区别

请参阅MSDN的Windows开发中心上的:

连接绑定并不是大多数数据所需要的唯一东西 绑定场景。要使单向或双向绑定有效, 源属性必须支持传播的更改通知 绑定到绑定系统,从而绑定到目标。对于自定义绑定源, 这意味着属性必须支持INotifyPropertyChanged

这可以很容易地从DependencyProperty的连接中完成


dymanoid:这是一个完全配对的完全运行的样本,以便有帮助的人可以尝试它。这显然不是生产代码。我当然希望人们会欣赏这种简单。(TopData、MiddleData、BottomData等名称都应该给出)也许你应该将这个问题标记为
windowsphone
?我无法将您的示例代码导入到
WPF
应用程序中。谢谢-我尝试了上述所有项目。这适用于Windows 8.1和Phone 8.1。在这种情况下,它们是相同的代码。我在“本地机器”上运行,在这个例子中,它做了和以前一样的事情。。。偶尔更新为1或根本不更新为0。F
<ItemsControl x:Name="BottomItemsControl" ItemsSource="{Binding Path=This}" ...
<ItemsControl x:Name="BottomItemsControl" ItemsSource="{Binding}"...
public class BottomData : DependencyObject, INotifyPropertyChanged
{
    public string Name { get; set; }

    public static readonly DependencyProperty ValueProperty =
        DependencyProperty.Register("Value", typeof(double), typeof(BottomData), new PropertyMetadata(0d,new PropertyChangedCallback(OnValueChanged)));

    public double Value
    {
        get { return (double)this.GetValue(ValueProperty); }
        set { base.SetValue(ValueProperty, value); }
    }

    public BottomData(string name, double value)
    {
        this.Name = name;
        this.Value = value;
    }

    private static void OnValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        BottomData bd = d as BottomData;
        bd.NotifyPropertyChanged("Value");
    }

    void NotifyPropertyChanged(string propName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propName));
        }
    }
    public event PropertyChangedEventHandler PropertyChanged;
}