2016-06-17 9 views
2

私はC#UWP開発で新しく、実行時にTextBlockの値を変更しようとしていますが、バインディングが正しく機能しません。テキストブロックバインディングが実行時に更新されない

XAMLのTextBlockのtextプロパティをINotifyPropertyChangedを持つ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> 
+0

あなたはRaisepropertychangeメソッドにブレークポイントを入れて、それが発射されたかどうかを確認することができますか? – riteshmeher

+0

外部リンクではなく、ご質問のインプレースコードを入力してください。ここで、[mcve]を与えることが重要である理由を見てください。 – dymanoid

+0

@riteshmeher RaisePropertyChangedは起動していませんが、何が問題なのでしょうか? – CGuiVi

答えて

0

銀の光とWPFとは異なり、デフォルトのバインディングは、パフォーマンス上の理由から、一つの時間です。 Bindingは、アプリケーションの起動時に1回だけ実行されます。片方向バインディングは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を使用するビューを変更しました。私はx:古いデータバインディングをバインドするのは、実行時ではなくコンパイル時にバインディングの問題を示すためです。これは、それが与えるパフォーマンスの拡張のほかにあります。 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> 

ページ:バインド

public sealed partial class MainPage : Page 
{ 
    public MainPaigeViewModel viewModel; 

    public MainPage() 
    { 
     this.InitializeComponent(); 

     viewModel = new MainPaigeViewModel(); 
    } 


} 
0

試してみてください。UWPでText="{Binding MyValue, Mode=TwoWay}"

+0

回答ありがとうございました。 Nehlしかし、まだ同じ問題 – CGuiVi

関連する問題