我使用自定义类来跟踪游戏中的日期,因为DateTime不允许虚构设置。我的类绑定到窗口中的Label
。初始化时,它显示正常,但在我尝试推进日期时拒绝更新。在位于ViewModel中的以下属性中,消息框确认setter已触发,但该值被视为相同且永远不会调用RaisePropertyChanged()
:
public Date Date
{
get { return DataManager.Data.Date; }
set
{
//Messagebox will display here...
if (DataManager.Data.Date == value)
return;
//...But not here
DataManager.Data.Date = value;
RaisePropertyChanged(() => Date);
}
}
我已尝试取出if语句,但仍然无法更新。
我已经尝试了几种更新Date
的方法,但没有一种方法有效。这是我能够完全触发setter的唯一方法(这在ViewModel中的命令中调用):
Date = Date.AddDays(1);
消息框确认这是正确更新日期(当然是在框内)。
以下是完整的Date.cs
课程:
public enum Season { Light, Shadow }
public class Date : ObservableObject
{
#region Members
private int _day;
#endregion
#region Properties
public int Year
{
get { return _day / 100; }
}
public Season Season
{
get { return (DayOfYear < 70) ? Season.Light : Season.Shadow; }
}
public int DayOfYear
{
get { return _day % 100; }
}
#endregion
#region Construction
public Date(int year, int day)
{
_day = (100 * year) + day;
}
#endregion
#region Methods
public Date AddDays(int value)
{
this._day += value;
return this;
}
public override string ToString()
{
return string.Format("{0} {1}, {2}", DayOfYear, Season, Year);
}
#endregion
}
这是XAML,也许它会有所帮助。我尝试了不同的绑定选项;没有工作。
<Label Content="{Binding Date}"
Grid.Row="1"
Grid.Column="4"
FontFamily="Pericles"
FontSize="16"
VerticalAlignment="Center"
HorizontalAlignment="Right" />
此时我不知道如何在视图中更新Date
。任何建议都将不胜感激。
更新:我应该提到我正在使用MVVM Light,这是ObservableObject
和RaisePropertyChanged
进来的地方。此外,我的ViewModel继承自MVVM Light的{ {1}}。其他绑定属性没有任何问题。
更新:根据Sniffer的建议,ViewModelBase
现在显示:
AddDays
用户界面仍然没有更新。
当我打电话给...
public Date AddDays(int value)
{
this._day += value;
RaisePropertyChanged(() => Year);
RaisePropertyChanged(() => Season);
RaisePropertyChanged(() => DayOfYear);
return this;
}
...在命令内部,Label不会更改,但MessageBox会正确显示更新日期。
更新+可能的解决方案:我已成功完成工作。
在ViewModel中:
Date = Date.AddDays(1);
RaisePropertyChanged(() => Date);
System.Windows.MessageBox.Show(Date.ToString());
...并在命令中
public string Date
{
get { return DataManager.Data.Date.ToString(); }
}
在DataManager.Data.Date.AddDay(1);
RaisePropertyChanged(() => Date);
:
Date.cs
使用此方法不需要提升属性,public void AddDay(int value)
{
this._day += value;
}
甚至不需要观察。鉴于这些信息,如果有人可以提出改进建议,我全都听见了。如果没有,我会用它来称呼它。
答案 0 :(得分:3)
这种情况正在发生,因为尽管您的Date
类实现了Observable
,但它没有为PropertyChangedEvent
类中的任何属性引发任何Date
。因此,如果您将日期属性设置为完全为其分配一个新日期,那么您的视图将会更新:Date = new Date(2013, 69);
例如,为了解决此问题,您需要为Date
中的每个属性提升PropertyChangedEvent以及那些是Year, DayOfYear, Season
。
答案 1 :(得分:1)
问题中的代码段显示Label
绑定到Date
属性,而不是日期的各个属性。用户界面无法知道日期的内容发生了变化。
听起来你需要在视图模型中的某处添加RaisePropertyChanged(() => Date)
,但是如果没有看到更多的代码,就很难说它放在哪里。也许在致电AddDays()
之后?
答案 2 :(得分:1)
您认为您的XAML代码有什么作用?
<Label Content="{Binding Date}"
Grid.Row="1"
Grid.Column="4"
FontFamily="Pericles"
FontSize="16"
VerticalAlignment="Center"
HorizontalAlignment="Right" />
输出会像89 Shadow 900
那样正确但这样做是错误的,因为它使用了你的toString()
这不是可绑定的AFAIK
但你还有其他两个选择
第一个
在日期
中创建新媒体资源public string dateString
{
get { return this.ToString(); }
} // don't forget to raise it in your addDate
XAML绑定部分
<Label DataContext="{Binding Date}" Content="{Binding dateString}"
Grid.Row="1"
Grid.Column="4"
FontFamily="Pericles"
FontSize="16"
VerticalAlignment="Center"
HorizontalAlignment="Right" />
<强>第二强>
使用Mutlibinding
<TextBlock DataContext="{Binding Date}">
<TextBlock.Text>
<MultiBinding StringFormat='{}{0} {1}, {2}'>
<Binding Path='DayOfYear' />
<Binding Path='Season' />
<Binding Path='Year' />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
答案 3 :(得分:0)
DataManager.Data.Date是什么?你刚刚发布了Date类,但是在你的setter和getter中没有任何意义,所以我认为你的Data对象中有一个属性?如果是,那么请发布这个属性 - 如果这个proeprty调用onproperty在setter中你的绑定应该工作
编辑:我现在仔细阅读:)你绑定到Date类,你想看到.AddDays(1)被调用时的变化?如果你不直接绑定年,日和月,你应该尝试更新标签的datacontext。当你想在AddDays()上看到更改时,这当然不起作用 - 如果你设置一个新的Date属性,它就会起作用。
<Label DataContext="{Binding Date}" Content="{Binding .}"
Grid.Row="1"
Grid.Column="4"
FontFamily="Pericles"
FontSize="16"
VerticalAlignment="Center"
HorizontalAlignment="Right" />
但是如果你直接绑定到年,日和月 - 你应该在每个上调用onpropertychanged并使用多路转换器。
问题是你绑定到一个Date对象,并希望看到日期对象内的某些东西发生变化时的变化(例如,使用AddDays(1)),这种变化不像你那样工作。