所以我似乎陷入了一个循环(没有双关语意)。 我创建了我的视图,其中包含一个Button控件和一个TextBlock控件。 我已经将我的按钮绑定到一个命令,该命令从我的模型中调用一个方法。
XAML
<Grid>
<TextBlock Text="{Binding CounterValue}" Width=" 100" Height="20"></TextBlock>
<Button Command="{Binding startCommand}" Content="Button" HorizontalAlignment="Left" Margin="472,230,0,0" VerticalAlignment="Top" Width="75"/>
</Grid>
这是StartCommand,你可以忽略它,这里没什么特别的
class StartCommand : ICommand
{
private Action _startCommand;
public StartCommand(Action StartCommand)
{
_startCommand = StartCommand;
}
public bool CanExecute(object parameter)
{
return true;
}
public void Execute(object parameter)
{
_startCommand?.Invoke();
}
public event EventHandler CanExecuteChanged;
}
然后我们得到的模型是一个单独的cs文件。
class CounterModel
{
static DispatcherTimer calcTimer = new DispatcherTimer();
public StartCommand startCommand { get; } = new StartCommand(Start);
public CounterModel()
{
CounterValue = 10;
}
private static int _counterValue;
public static int CounterValue
{
get { return _counterValue; }
set
{
_counterValue = value;
}
}
public static void Start()
{
//Start some stuff..
Calculate();
}
public static void Calculate()
{
calcTimer.Tick += CalcTimer_Tick;
calcTimer.Interval = TimeSpan.FromSeconds(2);
calcTimer.Start();
}
private static void CalcTimer_Tick(object sender, EventArgs e)
{
PerformanceCounter cpuCounter = new PerformanceCounter
("Process", "% Processor Time", "Firefox", true);
CounterValue = (int)cpuCounter.NextValue();
}
}
我现在的问题是,当我点击我的开始按钮时它没有做任何事情......或者它很好但是我的文本属性没有正常更新,该值不对应于计时器tick事件分配给它的新值。
我尝试实现接口INotifyPropertyChanged
,但我不能这样做。
private static int _counterValue;
public static int CounterValue
{
get { return _counterValue; }
set
{
_counterValue = value;
OnPropertyChanged("startCommand");
}
}
因为OnPropertyChanged
然后需要是静态的,这又会让我陷入一个全新的兔子,我不应该开始。
我需要我的属性是静态的,所以我可以在Tick事件中使用它们,这个事件是从我的计算方法调用的,它在Start()
内被调用
开始需要是静态的,因为我从很多其他类调用它。无论哪种方式..
如何处理我的属性是静态的还是使用INotifyPropertyChanged oooor ..如何在没有INotifyPropertyChanged
的情况下更新TextBlock文本值
不删除Start()
中的静态修改器是的,我确实设置了DataContext
public MainWindow()
{
InitializeComponent();
DataContext = new CounterModel();
}
答案 0 :(得分:0)
我理解你的情景。但是你的Start()的可访问性不是更多的设计问题吗?通过实现单例模式以在每次调用start方法时从start方法获取值,并且不使Start()成为静态,您可以实现两全其美。您可以看到以下示例:
public class CounterModel : INotifyPropertyChanged
{
private static CounterModel _instance = new CounterModel();
public static CounterModel Instance { get { return _instance; } }
private CounterModel()
{
CounterValue = 10;
startCommand = new StartCommand(Start);
}
static DispatcherTimer calcTimer = new DispatcherTimer();
public StartCommand startCommand { get; }
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
private int _counterValue;
public int CounterValue
{
get
{
return _counterValue;
}
set
{
_counterValue = value;
NotifyPropertyChanged();
}
}
public void Start()
{
//Start some stuff..
Calculate();
}
public void Calculate()
{
calcTimer.Tick += CalcTimer_Tick;
calcTimer.Interval = TimeSpan.FromSeconds(2);
calcTimer.Start();
}
private void CalcTimer_Tick(object sender, EventArgs e)
{
PerformanceCounter cpuCounter = new PerformanceCounter
("Process", "% Processor Time", "Explorer", true);
CounterValue = (int)cpuCounter.NextValue();
}
}
一旦单例模式到位,所有必需的方法都不需要是静态的,并且您仍然可以始终获得它的公共实例。现在,您可以在MainWindow中调用该实例。
public MainWindow()
{
InitializeComponent();
DataContext = CounterModel.Instance;
}
在您的视图中,您会相应地进行以下更改,
<TextBlock Text="{Binding CounterValue,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Width="100" Height="20"></TextBlock>
<Button Command="{Binding startCommand}" Content="Button" HorizontalAlignment="Left" Margin="472,230,0,0" VerticalAlignment="Top" Width="75"/>
ICommand看起来很好,所以我没有将其添加为答案的一部分。如果方法适合你,请告诉我。