我是c#UWP开发的新手,我正在尝试在运行时更改TextBlock的值,但绑定无法正常工作。
我正在使用INotifyPropertyChanged将XAML中TextBlock的text属性绑定到ViewModel上的属性,并且值每10秒更改一次。
我不知道这是否是正确的方法,有人可以帮助我吗?
提前致谢!
class MainPaigeViewModel : INotifyPropertyChanged
{
public MainPaigeViewModel()
{
Task.Run(async () =>
{
Random random = new Random();
while (true)
{
await Task.Delay(10000);
int newValue = random.Next(-40, 40);
_MyValue = newValue.ToString();
Debug.WriteLine(MyValue);
}
});
}
//Properties
private string _MyValue;
public string MyValue
{
get { return _MyValue; }
set
{
_MyValue = value;
RaisePropertyChanged("MyValue");
}
}
//INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChanged(string name)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
}
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:CountDown2"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ViewModels="using:CountDown2.ViewModels"
x:Class="CountDown2.MainPage"
mc:Ignorable="d">
<Page.DataContext>
<ViewModels:MainPaigeViewModel/>
</Page.DataContext>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<RelativePanel VerticalAlignment="Center" HorizontalAlignment="Center">
<TextBlock Text="{Binding MyValue, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
Width="100"
Height="40"
TextAlignment="Center"
FontSize="20"
/>
</RelativePanel>
</Grid>
</Page>
答案 0 :(得分:1)
尝试:Text="{Binding MyValue, Mode=TwoWay}"
答案 1 :(得分:1)
在UWP中,与银光和WPF不同,默认绑定是性能原因的一次。绑定仅在应用程序启动时发生一次。单向绑定是WinRT,Silverlight和wpf的默认值。这意味着视图将被更新,但更新视图将不会更新视图模型。双向绑定将更新视图和视图模型。
因此,对于示例中的<TextBlock>
,建议使用One Way
绑定。
在<TextBox>
中,建议对用户输入使用Two Way
绑定。
我发现了一些导致绑定失败的小错误...所以我更改了viewmodel ...正在使用私有属性而不是公共属性。由于代码正在更新线程中的值,然后尝试跨线程封送对象,因此添加了一个调度程序。还为所有视图模型添加了一个公共基类。这使得属性绑定更容易,它在重构属性名称时停止绑定问题。
Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync
public class MainPaigeViewModel: ViewModelBase
{
public MainPaigeViewModel()
{
Task.Run(async () =>
{
Random random = new Random();
while (true)
{
await Task.Delay(1000);
int newValue = random.Next(-40, 40);
try
{
await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
() => {
MyValue = newValue.ToString();
});
}
catch (Exception ex)
{
string s = ex.ToString();
}
Debug.WriteLine(MyValue);
}
});
}
//Properties
private string _MyValue;
public string MyValue
{
get { return _MyValue; }
set
{
_MyValue = value;
OnPropertyChanged();
}
}
}
public abstract class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged = delegate { };
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
我还将视图更改为使用x:binding。我喜欢x:绑定旧数据绑定,因为它在编译时而不是在运行时显示绑定问题。这除了它提供的性能增强之外。
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<RelativePanel VerticalAlignment="Center" HorizontalAlignment="Center">
<TextBlock Text="{x:Bind viewModel.MyValue, Mode=OneWay}"
Width="100"
Height="40"
TextAlignment="Center"
FontSize="20"
/>
</RelativePanel>
</Grid>
x:bind
的代码页面public sealed partial class MainPage : Page
{
public MainPaigeViewModel viewModel;
public MainPage()
{
this.InitializeComponent();
viewModel = new MainPaigeViewModel();
}
}