TextBlock UI未使用INotifyPropertyChanged更新

时间:2016-11-20 00:15:19

标签: c# wpf

XAML:

<Button Content="Refresh" Margin="0,5,0,0" Width="120" Click="RefreshPlayers"/>
                <StackPanel Orientation="Horizontal" Margin="0,5,0,0">
                    <StackPanel.Resources>
                        <viewModels:LastRefreshedViewModel x:Key="LastRefreshedViewModel"/>
                    </StackPanel.Resources>
                    <TextBlock Text="Last Refreshed:" HorizontalAlignment="Center"/>
                    <TextBlock DataContext="{StaticResource LastRefreshedViewModel}" Text="{Binding LastRefreshTimeString}" Margin="3,0,0,0"/>
                </StackPanel>

主窗口:

        private void RefreshPlayers(object sender, RoutedEventArgs e)
    {
        RefreshPlayers();
    }

    private void RefreshPlayers()
    {
        GetSteamInfo();
        _lastRefreshedViewModel.Reset();
    }

视图模型:

 public class LastRefreshedViewModel : PropertyChangedBase
{
    private int _lastRefreshTime;

    public string LastRefreshTimeString
    {
        get {
            return _lastRefreshTime == 0 ? "Never" : _lastRefreshTime + " min";
        }
    }

    public int LastRefreshTime
    {
        get { return _lastRefreshTime; }
        set { 
        {
            if (value == _lastRefreshTime) {
                return;
            }

            _lastRefreshTime = value;
            NotifyOfPropertyChange(() => LastRefreshTimeString);
            NotifyOfPropertyChange(() => LastRefreshTime);
        }}
    }

    public LastRefreshedViewModel()
    {
        _lastRefreshTime = 0;
    }

    public void Update()
    {
        LastRefreshTime++;
    }

    public void Reset()
    {
        LastRefreshTime = 1;
    }

每当我按“刷新”时,LastRefreshTime会更新,但Textblock UI不会。我怀疑这是一个线程问题,但我尝试使用后台工作者,线程池和调度程序失败了。

1 个答案:

答案 0 :(得分:0)

您应该为任何控件的父级设置datacontext(在您的案例中为textblock)。 例如

XAML:

<Button Content="Refresh" Margin="0,5,0,0" Width="120" Click="RefreshPlayers"/>
    <StackPanel Orientation="Horizontal" Margin="0,5,0,0">
        <StackPanel.Resources>
            <viewModels:LastRefreshedViewModel x:Key="LastRefreshedViewModel"/>
        </StackPanel.Resources>
        <TextBlock Text="Last Refreshed:" HorizontalAlignment="Center"/>
        <Grid x:Name="myGrid" DataContext="{StaticResource LastRefreshedViewModel}">
            <TextBlock Text="{Binding LastRefreshTimeString}" Margin="3,0,0,0"/>
        </Grid>
    </StackPanel>

代码背后:

private void RefreshPlayers(object sender, RoutedEventArgs e)
    {            
        if(myGrid.DataContext != null)
        {
            var viewModel = myGrid.DataContext as LastRefreshedViewModel;
            if(viewModel != null)
            {
                viewModel.Reset();
            }
        }
    }

查看型号:

public class LastRefreshedViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    // This method is called by the Set accessor of each property.
    // The CallerMemberName attribute that is applied to the optional propertyName
    // parameter causes the property name of the caller to be substituted as an argument.
    private void NotifyPropertyChanged(String propertyName = "")
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    private int _lastRefreshTime;

    public string LastRefreshTimeString
    {
        get
        {
            return _lastRefreshTime == 0 ? "Never" : _lastRefreshTime + " min";
        }
    }

    public int LastRefreshTime
    {
        get { return _lastRefreshTime; }
        set
        {
            {
                if (value == _lastRefreshTime)
                {
                    return;
                }

                _lastRefreshTime = value;
                NotifyPropertyChanged("LastRefreshTimeString");
                NotifyPropertyChanged("LastRefreshTime");
            }
        }
    }

    public LastRefreshedViewModel()
    {
        _lastRefreshTime = 0;
    }

    public void Update()
    {
        LastRefreshTime++;
    }

    public void Reset()
    {
        LastRefreshTime = 1;
    }
}