0

DateTime では架空の設定が許可されていないため、カスタム クラスを使用してゲームの日付を追跡しています。ウィンドウ内の a にクラスをバインドしてLabelいます。初期化すると問題なく表示されますが、日付を進めようとすると更新が拒否されます。ViewModel にある次のプロパティでは、セッターが起動したことを確認するメッセージ ボックスが表示されますが、値は同じと見なされ、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たが、どれもうまくいきませんでした。これは、セッターをまったく起動させることができた唯一の方法です(これは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ましRaisePropertyChangedViewModelBase。その他のバインドされたプロパティは問題なく機能します。

更新: Sniffer の提案によると、次のAddDaysようになります。

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

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

    return this;
}

UI はまだ更新されません。

電話したら…

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さえありません。この情報があれば、誰かが改善を提案できるなら、私はすべて耳にします。そうでない場合は、これで 1 日と呼びます。

4

4 に答える 4

3

これは、Dateクラスが実装しているにもかかわらず、クラスのどのプロパティに対しても s をObservable発生させないために発生しています。したがって、Date プロパティを設定して、次のように新しい Date を完全に割り当てた場合にのみ、ビューが更新されます。たとえば、これを修正するには、各プロパティに対して PropertyChangedEvent を発生させる必要があります。PropertyChangedEventDateDate = new Date(2013, 69);DateYear, DayOfYear, Season

于 2013-06-24T21:40:48.983 に答える
1

質問のコード スニペットは、日付の個々のプロパティではなくLabel、プロパティにバインドされていることを示しています。DateUI は、日付の内容が変更されたことを知る方法がありません。

ビュー モデルのどこかに追加する必要があるように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が、これを使用したため、それを行うのは間違った方法ですAFAIKtoString()はバインド可能ではありません

しかし、他に 2 つのオプションがあります

最初の1つ

あなたの日付に新しいプロパティを作成します

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

2番

マルチバインディングを使用する

<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 クラスを投稿するだけですが、それはセッターとゲッターでは意味がないので、Data オブジェクトのプロパティだと思いますか? はいの場合は、pls がこのプロパティを投稿します。このプロパティがセッターで 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 を呼び出し、マルチコンバーターを使用する必要があります。

問題は、日付オブジェクトにバインドし、日付オブジェクト内の何かが変更されたときに変更を確認したいことです (たとえば、AddDays(1) を使用)。

于 2013-06-25T05:47:52.393 に答える