0

我正在使用自定义类来跟踪游戏中的日期,因为 DateTime 不允许虚构设置。我将课程绑定到Label我的窗口中的 a 。初始化时,它显示正常,但当我尝试提前日期时拒绝更新。在 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,这是进来的地方ObservableObjectRaisePropertyChanged此外,我的 ViewModel 继承自 MVVM Light 的ViewModelBase. 其他绑定属性工作没有任何问题。

更新: Per Sniffer 的建议,AddDays现在为:

public Date AddDays(int value)
{
    this._day += value;

    RaisePropertyChanged(() => Year);
    RaisePropertyChanged(() => Season);
    RaisePropertyChanged(() => DayOfYear);

    return this;
}

用户界面仍然没有更新。

当我打电话...

Date = Date.AddDays(1);
RaisePropertyChanged(() => Date);
System.Windows.MessageBox.Show(Date.ToString());

...在命令内部,Label 不会更改,但 MessageBox 会正确显示更新的日期。

更新+可能的解决方案:我已经设法让事情正常进行。

在视图模型中:

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

这种方法Date不需要提升属性,甚至不必是可观察的。鉴于此信息,如果有人可以提出改进建议,我会全力以赴。如果没有,我会就此收工。

4

4 回答 4

3

发生这种情况是因为尽管您的Date类实现Observable了但它没有为类PropertyChangedEvent上的任何属性引发任何 s Date。因此,只有在您设置 Date 属性并像这样完全为其分配一个新的 Date 时,您的视图才会更新:Date = new Date(2013, 69);例如,要解决此问题,您需要为您的每个属性引发DatePropertyChangedEvent Year, DayOfYear, Season

于 2013-06-24T21:40:48.983 回答
1

您问题中的代码片段显示Label绑定到Date属性,而不是日期的各个属性。UI 无法知道日期的内容已更改。

听起来您需要RaisePropertyChanged(() => Date)在视图模型中添加某个位置,但是如果没有看到更多代码,就很难说将它放在哪里。也许在调用之后AddDays()

于 2013-06-24T22:32:21.777 回答
1

你认为你的 XAML 代码是做什么的?

<Label Content="{Binding Date}"
           Grid.Row="1"
           Grid.Column="4"
           FontFamily="Pericles"
           FontSize="16"
           VerticalAlignment="Center"
           HorizontalAlignment="Right" />

输出将正确地类似于89 Shadow 900但那是错误的方法,因为它使用了你的toString()this is not bindable AFAIK

但您还有 2 个其他选择

第一

在您的日期创建一个新属性

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

第二

使用多重绑定

<TextBlock DataContext="{Binding Date}">
    <TextBlock.Text>
        <MultiBinding StringFormat='{}{0} {1}, {2}'>
            <Binding Path='DayOfYear' />
            <Binding Path='Season' />
            <Binding Path='Year' />
        </MultiBinding>
    </TextBlock.Text>
</TextBlock>
于 2013-06-25T07:01:19.440 回答
0

DataManager.Data.Date 这是什么?您只是发布 Date 类,但这在您的 setter 和 getter 中没有任何意义,所以我假设这是您的 Data 对象中的一个属性?如果是,那么请发布这个属性 - 如果这个属性调用 onpropertychanged 在设置器中你的绑定应该工作

编辑:我现在更仔细地阅读了:) 你绑定到 Date 类并且你想在调用 .AddDays(1) 时看到更改?如果您不直接绑定到年、日和月,则应尝试更新标签的数据上下文。当您想查看 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)),这不是您的工作方式。

于 2013-06-25T05:47:52.393 回答