c# - 了解将数据从页面传递到用户控件
问题描述
我一直在努力解决如何在页面和 UserControl 之间传递数据,并且可以使用一些说明来说明我可能做错了什么。如果我删除代码的数据部分并仅用 TextBlocks 替换它,我知道 UserControl 正在工作。
我确实知道 NetWorth 正在显示,但只是看不出为什么List<Account>
没有传递。我不知道我在这里做错了什么。
PanelNavigation.xaml
<!-- Navigation Section -->
<ScrollViewer HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Auto" CanContentScroll="True" Grid.Row="1" Margin="0,0.333,0,0" Grid.ColumnSpan="2">
<UserControls:NavigationPanel DataContext="{Binding Accounts}"/>
</ScrollViewer>
<!-- Networth Panel -->
<Grid Grid.Row="2" Height="40">
<Border BorderThickness="0,1,0,0" BorderBrush="{StaticResource MenuBarBrush}" Background="{StaticResource BackgroundLightBrush}">
<Grid Margin="5,5,10,5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock Margin="10,1,10,1" FontSize="16" FontWeight="Normal" Grid.Column="0" Foreground="#FF346C9C" Text="Net Worth" />
<TextBlock FontSize="16" FontWeight="Normal" Grid.Column="1"
HorizontalAlignment="Right" Text="{Binding NetWorth, Converter={StaticResource CurrencyConverter}}"
Foreground="{Binding NetWorth, Converter={StaticResource ChangeColor}}"/>
</Grid>
</Border>
</Grid>
PanelNavigation.xaml.cs
using APTest.ViewModels;
using System.Windows.Controls;
namespace APTest.Views
{
/// <summary>
/// Interaction logic for PanelNavigation.xaml
/// </summary>
public partial class PanelNavigation : Page
{
public PanelNavigation()
{
InitializeComponent();
this.DataContext = new VMNavigationPanel(this);
}
}
}
导航面板.xaml
<UserControl x:Class="APTest.UserControls.NavigationPanel"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:UserControls="clr-namespace:APTest.UserControls"
mc:Ignorable="d"
d:DesignHeight="800" d:DesignWidth="400">
<StackPanel>
<StackPanel>
<ItemsControl x:Name="DataTest" ItemsSource ="{Binding Accounts}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding TotalBalance}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</StackPanel>
</UserControl>
导航面板.xaml.cs
using System.Windows.Controls;
namespace APTest.UserControls
{
public partial class NavigationPanel : UserControl
{
public NavigationPanel()
{
InitializeComponent();
}
}
最后
VMNavigationPanel.cs
using AccountingPlus.ViewModels;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
namespace APTest.ViewModels
{
class VMNavigationPanel : BaseViewModel
{
private Page mPage;
private ObservableCollection<Account> accounts;
public ObservableCollection<Account> Accounts {
get => accounts;
set {
accounts = value;
OnPropertyChanged();
}
}
public double NetWorth { get; set; } = 127492.30;
public VMNavigationPanel(Page page)
{
mPage = page;
Accounts = new ObservableCollection<Account>();
Account test = new Account();
test.TotalBalance = 100234.23;
Accounts.Add(test);
}
}
public class Account
{
public double TotalBalance {get; set;}
}
}
BaseViewModel.cs
using PropertyChanged;
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace APTest
{
[AddINotifyPropertyChangedInterface]
class BaseViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged = (Sender, e) => { };
protected void OnPropertyChanged([CallerMemberName] string name = null)
{
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
}
}
解决方案
首先,您需要模型中的属性来绑定对象。您不能绑定字段。
这样您的 Account 类应该是这样的:
public class Account
{
public double TotalBalance { get; set; }
}
还要记住这一点,要在 WPF 中更新 UI,我们需要使用 ObservableCollections。例如,如果您单击一个按钮并将一个项目添加到您的 Accounts 集合中,则该项目将在您的集合中,但在 UI 中,如果您使用 List 集合,您将看不到更新的结果,这就是您需要使用 ObservableCollections 的原因。 https://docs.microsoft.com/en-us/dotnet/api/system.collections.objectmodel.observablecollection-1?view=netcore-3.1
另一件事是您的绑定拼写错误。在您的 NavigationPanel.xaml 中,它应该是 TotalBalance。
<TextBlock Text="{Binding TotalBalnce}" />
这是您的视图模型的工作代码:
我还为您实现了 INotifyPropertyChanged 接口,但没有与任何其他属性一起使用。
class VMNavigationPanel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged<T>(ref T property, T value, [CallerMemberName] string propertyName = null)
{
property = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
private Page mPage;
public double NetWorth { get; set; } = 127492.30;
private ObservableCollection<Account> accounts;
public ObservableCollection<Account> Accounts
{
get => accounts;
set
{
accounts = value;
}
}
public VMNavigationPanel(Page page)
{
mPage = page;
Accounts = new ObservableCollection<Account>();
Account test = new Account();
test.TotalBalance = 100234.23;
Accounts.Add(test);
}
}
public class Account
{
public double TotalBalance { get; set; }
}
推荐阅读
- r - 如何在不登录的情况下将谷歌凭据放入闪亮的网络应用程序
- javascript - 为什么在建立连接后绑定事件监听器?
- pandas - 将多路 pandas.crosstab 转换为 xarray
- karate - 具有空手道 1.0.1 的 Chrome 驱动程序没有获取帧树
- ios - 如果我锁定屏幕或 iPhone 开始进入睡眠状态,但我从未退出应用程序,那么该应用程序是否仍被视为后台运行?
- python - 从 xml 错误中获取值:AttributeError:“NoneType”对象没有属性“文本”
- vue.js - Vue 3 - 如何在根组件中包含组件和 mixin?
- macos - OSX - 限制对菜单项的访问
- heroku - Shopify 脚本标签:302 CORB 错误,脚本标签重定向到身份验证流程
- cookies - a.abc.com 和 b.abc.com 之间的第一方 Cookie