设想
我有两个班级:
Fruit
有两个数据成员FruitName
和FruitColor
Presentation
还有两个成员ForeColor
和FontName
ListBox 的ItemsSource
属性设置为List<Fruit>
。并列出了水果。
但是,我想更改 TextBlock 控件的 FontFamily 和 Foreground,这应该会在我将 Presentation 实例设置为 ListBox 时立即反映出来。
问题
问题是
当我调用 时
btnChangeColor_Click()
,我收到一个异常“对象引用未设置为对象的实例”。在INotifyPropertyChanged()
方法中。正是这里...await dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); });
我想用一些显示 FruitName 和 FruitColor 的 Fruits 对象设置 ListBox。我还想更改字体名称和显示 FruitName 和 FruitColor 的 TextBlock 的前景,以便更改颜色和字体名称应立即反映
代码
测试RealTimeUIUpdate.xaml
<Page
x:Class="dataStorage_And_AppSettings.TestingRealTimeUIUpdate"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:dataStorage_And_AppSettings"
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}">
<StackPanel>
<ListBox x:Name="lstFruits" Height="400" Background="Aqua">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock x:Name="lblFruitName" Text="{Binding Fruits.FruitName}" Foreground="{Binding Presentations.ForeColor}" FontFamily="{Binding Presentations.FontName}" />
<TextBlock x:Name="lblFruitColor" Text="{Binding Fruits.FruitColor}" Foreground="{Binding Presentations.ForeColor}" FontFamily="{Binding Presentations.FontName}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<ListBox x:Name="lstColors" Height="175" Background="Goldenrod" >
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock x:Name="lblFruitName" Text="FontColors And Font Name" Foreground="{Binding Presentation.ForeColor}" FontFamily="{Binding Presentation.FontName}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Button x:Name="btnReloadFruits" Content="ReloadBasket" Click="btnReload_Click" />
<Button x:Name="btnChangeColor" Content="ChangeColor" Click="btnChangeColor_Click" />
</StackPanel>
</Grid>
</Page>
TestingRealTimeUIUpdate.CS
using System;
using System.Collections.Generic;
using System.Linq;
using Windows.UI;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
namespace dataStorage_And_AppSettings
{
public sealed partial class TestingRealTimeUIUpdate : Page
{
private Comp FruitBasket;
private List<Presentation> PresentationForFruitBasket = new List<Presentation>
{
new Presentation { FontName = "Arial", ForeColor = new SolidColorBrush(Colors.Green) },
new Presentation { FontName = "Verdana", ForeColor = new SolidColorBrush(Colors.Yellow) },
new Presentation { FontName = "Times New roman", ForeColor = new SolidColorBrush(Colors.Brown) },
new Presentation { FontName = "Tahoma", ForeColor = new SolidColorBrush(Colors.Red) },
};
private List<Fruit> FruitForFruitBasket = new List<Fruit>
{
new Fruit { FruitName= "Mango", FruitColor="Yellow" },
new Fruit {FruitName = "Banana", FruitColor= "Yellow" },
new Fruit { FruitName="Grapes", FruitColor="Green"},
new Fruit {FruitName="Tomato", FruitColor="Red" }
};
public TestingRealTimeUIUpdate()
{
this.InitializeComponent();
}
private void btnReload_Click(object sender, RoutedEventArgs e)
{
List<Comp> lstFruitBasket = new List<Comp>();
foreach( var item in FruitForFruitBasket)
{
FruitBasket = new Comp();
FruitBasket.Fruits = item;
FruitBasket.Presentations = PresentationForFruitBasket.ElementAt(2);
lstFruitBasket.Add(FruitBasket);
}
lstFruits.ItemsSource = lstFruitBasket;
}
private void btnChangeColor_Click(object sender, RoutedEventArgs e)
{
Random rnd = new Random();
FruitBasket.Presentations = PresentationForFruitBasket.ElementAt(rnd.Next(0, 3));
}
}
public class Comp : BindableBase
{
Fruit fruits = new Fruit();
Presentation presentations = new Presentation();
public Fruit Fruits
{
get { return fruits; }
set { SetProperty(ref fruits, value); }
}
public Presentation Presentations
{
get { return presentations; }
set { SetProperty(ref presentations, value); }
}
}
public class Fruit:BindableBase
{
private string fruitname;
private string fruitcolor;
public string FruitName
{
get { return fruitname; }
set { SetProperty(ref fruitname, value); }
}
public string FruitColor
{
get { return fruitcolor; }
set { SetProperty(ref fruitcolor, value); }
}
}
public class Presentation : BindableBase
{
private SolidColorBrush forecolor;
private string fontname;
public SolidColorBrush ForeColor
{
get { return forecolor; }
set { SetProperty(ref forecolor, value); }
}
public string FontName
{
get { return fontname; }
set { SetProperty(ref fontname, value); }
}
}
}
BindableBase.cs
using System;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using Windows.UI.Core;
namespace IQ.Main.ViewModels
{
public abstract class BindableBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private CoreDispatcher dispatcher;
protected bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = "")
{
if (Object.Equals(storage, value))
{
return false;
}
storage = value;
NotifyPropertyChanged(propertyName);
return true;
}
internal virtual async void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
try
{
await dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
});
}
catch (Exception ex) { Debug.WriteLine(ex.Message); }
}
}
}
}