【问题标题】:Textblock binding does not update in RunTime文本块绑定不会在运行时更新
【发布时间】:2016-06-17 12:03:50
【问题描述】:

我是 C# UWP 开发的新手,我正在尝试在运行时更改 TextBlock 的值,但绑定无法正常工作。

我正在使用 INotifyPropertyChanged 将 XAML 中 TextBlock 的文本属性绑定到 ViewModel 上的属性,并且值每 10 秒更改一次。

我不知道这样做是否正确,有人可以帮助我吗?

提前致谢!

this is the ViewModel code

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));
    }
}

 and the XAML code

   <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>

【问题讨论】:

  • 你能在 Raisepropertychange 方法中放一个断点并检查它是否正在触发吗?
  • 请在您的问题中就地提供您的代码,而不是作为外部链接。看看这里为什么给minimal reproducible example很重要。
  • @riteshmeher RaisePropertyChanged 没有触发,可能是什么问题?

标签: c# mvvm binding uwp uwp-xaml


【解决方案1】:

在 UWP 中,与银光和 WPF 不同,出于性能原因,默认绑定是 One time。绑定仅在应用程序启动时发生一次。一种绑定方式是 WinRT、Silverlight 和 wpf 的默认设置。这意味着视图将被更新,但更新视图不​​会更新视图模型。双向绑定将同时更新视图和视图模型。

所以对于示例中的&lt;TextBlock&gt;,建议使用One Way绑定。

&lt;TextBox&gt; 中,建议使用Two Way 绑定进行用户输入。

我发现了一些导致绑定失败的小错误……所以我更改了视图模型……正在使用私有属性而不是公共属性。由于代码正在更新线程中的值,然后尝试跨线程编组对象,因此添加了调度程序。还为所有视图模型添加了一个通用基类。这使属性绑定更容易一些,它在重构属性名称时停止了绑定问题。

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:binding 而不是旧的数据绑定,因为它在编译时而不是在运行时显示绑定问题。这是除了它提供的性能增强之外。

<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();
    }


}

【讨论】:

    【解决方案2】:

    试试看:Text="{Binding MyValue, Mode=TwoWay}"

    【讨论】:

    • 感谢@D 的回答。 Nehl,但仍然是同样的问题
    • 对于 TextBlock 没有意义。
    猜你喜欢
    • 2013-01-08
    • 1970-01-01
    • 2017-12-08
    • 2017-03-18
    • 1970-01-01
    • 1970-01-01
    • 2017-11-21
    • 2023-03-28
    • 1970-01-01
    相关资源
    最近更新 更多