C# UWP Xaml Textblock数据绑定-即使属性已更新,UI也不更新
首先是一个免责声明:我读了几十篇帖子,有数百个答案,但我还没有找到解决办法。我已经尝试用我能找到的每一种方法来解决这个问题,但是UI没有更新 我正在写一个UWP应用程序作为个人项目。在这个特定的场景中,我有一个网格,其中有一个指定的DataContext和一系列绑定到属性的TextBlock。我使用的是“绑定”而不是“x:Bind”,因为网格是ControlTemplate的一部分C# UWP Xaml Textblock数据绑定-即使属性已更新,UI也不更新,c#,xaml,data-binding,uwp,inotifypropertychanged,C#,Xaml,Data Binding,Uwp,Inotifypropertychanged,首先是一个免责声明:我读了几十篇帖子,有数百个答案,但我还没有找到解决办法。我已经尝试用我能找到的每一种方法来解决这个问题,但是UI没有更新 我正在写一个UWP应用程序作为个人项目。在这个特定的场景中,我有一个网格,其中有一个指定的DataContext和一系列绑定到属性的TextBlock。我使用的是“绑定”而不是“x:Bind”,因为网格是ControlTemplate的一部分 我已使用INotifyPropertyChanged实现了属性 我有后备领域 我已完成调试,属性已更新并保留指定
- 我已使用INotifyPropertyChanged实现了属性
- 我有后备领域
- 我已完成调试,属性已更新并保留指定的值
- 我已尝试使用UpdateSourceTrigger=PropertyChanged
- 我尝试过不同的模式-单向/双向等
<Grid
Grid.Row="1"
BorderBrush="{StaticResource SystemControlChromeLowAcrylicElementBrush}"
BorderThickness="2,0,2,2">
<Grid.DataContext>
<views:MenusPage />
</Grid.DataContext>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="auto" />
<ColumnDefinition Width="auto" />
<ColumnDefinition Width="152" />
<ColumnDefinition Width="152" />
<ColumnDefinition Width="152" />
<ColumnDefinition Width="152" />
<ColumnDefinition Width="152" />
</Grid.ColumnDefinitions>
<TextBlock
Grid.Row="0"
Grid.Column="0"
Grid.ColumnSpan="3"
Padding="15,0,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Center"
FontWeight="Bold"
Text="Totals" />
<Border
Grid.Row="0"
Grid.Column="3"
Margin="0,2,0,-2"
BorderBrush="{StaticResource SystemControlChromeLowAcrylicElementBrush}"
BorderThickness="2,0,0,0">
<TextBlock
Padding="10,0,0,0"
VerticalAlignment="Center"
FontWeight="Bold"
Text="{Binding CaloriesTotal, Mode=OneWay}" />
</Border>
<Border
Grid.Row="0"
Grid.Column="4"
Margin="0,2,0,-2"
BorderBrush="{StaticResource SystemControlChromeLowAcrylicElementBrush}"
BorderThickness="2,0,0,0">
<TextBlock
Padding="10,0,0,0"
VerticalAlignment="Center"
FontWeight="Bold"
Text="{Binding ProteinTotal}" />
</Border>
<Border
Grid.Row="0"
Grid.Column="5"
Margin="0,2,0,-2"
BorderBrush="{StaticResource SystemControlChromeLowAcrylicElementBrush}"
BorderThickness="2,0,0,0">
<TextBlock
Padding="10,0,0,0"
VerticalAlignment="Center"
FontWeight="Bold"
Text="{Binding FatTotal}" />
</Border>
<Border
Grid.Row="0"
Grid.Column="6"
Margin="0,2,0,-2"
BorderBrush="{StaticResource SystemControlChromeLowAcrylicElementBrush}"
BorderThickness="2,0,0,0">
<TextBlock
Padding="10,0,0,0"
VerticalAlignment="Center"
FontWeight="Bold"
Text="{Binding CarbTotal}" />
</Border>
<Border
Grid.Row="0"
Grid.Column="7"
Margin="0,2,0,-2"
BorderBrush="{StaticResource SystemControlChromeLowAcrylicElementBrush}"
BorderThickness="2,0,0,0">
<TextBlock
Padding="15,0,0,0"
VerticalAlignment="Center"
FontWeight="Bold"
Text="{Binding SugarTotal}" />
</Border>
</Grid>
财产变更:
public event PropertyChangedEventHandler PropertyChanged;
private void Set<T>(ref T storage, T value, [CallerMemberName]string propertyName = null)
{
if (Equals(storage, value))
{
return;
}
storage = value;
OnPropertyChanged(propertyName);
}
private void OnPropertyChanged(string propertyName) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
请将绑定DataContext用于主对象,而不是DataGrid:
<Window.DataContext>
<views:MenusPage />
</Window.DataContext>
我找到了解决方案,虽然我对它的实际工作原理感到目瞪口呆,而其他本该工作的“正常”解决方案却没有,但我无法理解 无论如何,感谢@jsmyth886和@Alexey在故障排除方面提供的帮助和建议 发布此问题后,我尝试将属性分离到另一个类中,在
块中引用
——失败
我尝试设置页面的DataContext
本身——失败
我的问题中的code>XAML是,ControlTemplate
的一部分,我甚至将块移出了控制模板,移到了页面本身,以消除与其他数据源的冲突-请注意,所有命名结构和路径都不同,所以最终不应该发生冲突-这也不起作用,所以——失败了
是@Alexey的回应让我换了一条思路,我的搜索最终让我找到了这篇文章,它解决了我的问题
我从网格中删除了以下datacontext:
<Grid.DataContext>
<views:MenusPage />
</Grid.DataContext>
最后将a Name属性添加到页面本身:
x:Name="_this"
成功了
我没有改变我设置属性的方式
我的属性仍然是根据问题定义的,我没有viewmodels或其他类,也没有在CodeBehind中设置DataContext
只需将DataContext=“{Binding ElementName=\u this}”
网格和x:Name=“\u this”
添加到页面中,就可以让UI每次反映对属性的更改
一个奇怪的简单解决方案
注意:尽管如此,当我尝试不同的事情时,当我在ContentTemplate之外的页面上有网格时,我在codebehindDataContext=this中设置了页面的DataContext代码>并开始填充,但仍然无法影响控件模板中的网格
所以,除非有我没有看到的冲突,或者因为我有其他不相关的数据源,并且直接分配给需要它的控件。。。我不明白为什么它现在可以使用这个简单的绑定
无论如何,感谢您的帮助,我希望这对以后的其他人有所帮助。如果您想从NavigationCacheMode(已启用/必需)中获益以提高性能,您必须在数据上下文更改时更新绑定
public MainPage()
{
this.InitializeComponent();
this.DataContextChanged += (s, e) => this.Bindings.Update();
}
对于每个属性上的集
,这是一个非常有趣的实现。调用Set
方法时,propertyName
是什么,是null还是正确的属性名?@jsmyth886属性名传递正确,每次填充的值都正确。我甚至尝试过Microsoft文档中规定的相同配置,其中传递的字符串值仍然会更新属性,但不会更新UI,这毫无意义。单步执行代码显示属性上设置了值。嗯,我刚刚尝试了您的实现,它对我很有效。但是我使用的是Caliburn框架,它已经实现了INotifyPropertyChanged
,所以我只是在集合中调用了它。调试时,输出窗口中是否存在任何绑定
错误?@jsmyth886只需运行调试以确保不会显示任何错误是否有可能创建了两次菜单页
,但只将一次附加到网格
,因此,看起来属性在代码中发生了更改,但实际上没有通知UI,因为网格附加了不同的实例?如果看不到更多的代码,就很难理解更改网格的DataContext
应该没有问题。我还要指出标记
不是UWP的一部分。@jsmyth886根元素是什么?使用它而不是网格,并将这些线立即放在这个根中element@Alexey我又给了你一次机会,但也失败了,还是不行。
<Grid ... DataContext="{Binding ElementName=_this}">
...
<TextBlock ... Text="{Binding CaloriesTotal}" />
...
</Grid>
x:Name="_this"
public MainPage()
{
this.InitializeComponent();
this.DataContextChanged += (s, e) => this.Bindings.Update();
}