【问题标题】:New Instance of Object Breaks Binding对象中断绑定的新实例
【发布时间】:2013-11-06 19:07:06
【问题描述】:

我有一个名为 Date 的类,它覆盖了它的 ToString 并通过一个属性返回它:

public string DateString
{
    get { return ToString(); }
}

我的Date 实例保存在容器类中并从那里进行操作。在 XAML 中,被覆盖的 ToString 显示如下:

<TextBlock Text="{Binding Container.Date.DateString, Source={StaticResource Locator}}" />

定位器在 App.xaml 中定义:

<data:Locator x:Key="Locator" />

Locator 类包括:

public class Locator
{
    static Locator()
    {
        Container = new GameContainer();
    }

    public static GameContainer Container { get; set; }
}

GameContainer 包括:

public class GameContainer
{
    public GameContainer()
    {
        Date = new Date();
    }

    public Date Date { get; set; }
}

我也尝试过使用 IOC 容器,但没有成功。

程序启动后,一切正常;单击按钮会增加日期(并在DateString 上调用RaisePropertyChanged)。但是,如果我创建容器的新实例或 Date 的新实例,则 UI 不再更新,我不知道为什么。它似乎只发生在用户交互发生之后;我可以在程序初始化的各个阶段创建一个新实例而没有任何问题,但是一旦单击按钮导致创建一个新实例,字符串就不再更新。

我已经尝试了所有我能想到的方法,但我似乎无法弄清楚是什么导致了这种情况发生。任何帮助将不胜感激。

更新:目前我的依赖属性如下:

public static readonly DependencyProperty ContainerProperty =
        DependencyProperty.Register("Container", typeof(GameContainer), typeof(Locator));

    public static GameContainer Container
    {
        get { return (GameContainer)GetValue(ContainerProperty); }
        set
        {
            SetValue(ContainerProperty, value);
        }
    }

我收到此错误:非静态字段、方法或属性“System.Windows.DependencyObject.GetValue(System.Windows.DependencyProperty)”需要对象引用

【问题讨论】:

  • However, if I create a new instance of the container or a new instance of Date, the UI no longer updates and I can't figure out why.: 你确定你是在绑定的Locator 的同一个实例上这样做吗?我问是因为 Locator 不是 static 类,所以你会有一些同步问题。
  • 将Locator设为静态没有区别。
  • 如何在 UI 上的绑定仍然相同的情况下创建容器的新实例?我怀疑您的 Locator 实例仍然绑定到 UI,这就是为什么当您创建一个新实例时它不会更新的原因。您希望何时创建新实例?
  • 我希望有一个 Button 或 MenuItem 覆盖当前的 GameContainer 并将其替换为新的并再次执行初始化逻辑。至少这是我试图实现的。
  • 也许我不太明白你的问题。您是否已经尝试从 ViewModel 更新 GameContainer 属性,触发按钮的 Click 事件?

标签: c# wpf xaml


【解决方案1】:

您似乎没有任何属性更改通知机制,这对于使Binding 正常工作非常重要。尝试实现INotifyPropertyChanged或创建对应的DependencyProperty,我将介绍在这种情况下使用DependencyProperty:

public class GameContainer : DependencyObject {
  public GameContainer() {
     Date = new Date();
  }
  public static readonly DependencyProperty DateProperty = 
       DependencyProperty.Register("Date", typeof(Date), typeof(GameContainer));
  public Date Date {
     get { return (Date) GetValue(DateProperty);}
     set {
        SetValue(DateProperty, value);
     }
  }
}

注意:对Locator 类中的属性Container 执行相同操作。

我真的很困惑Binding 如何处理静态属性。这是我能想到的所有应该尝试的代码:

public class Locator {       
   static Locator() {
    Container = new GameContainer();
   }
   public static event EventHandler ContainerChanged;
   static GameContainer container;
   public static GameContainer Container {
     get { return container;}
     set {
        if(container != value){
          container = value;
          var handler = ContainerChanged;
          handler(null, EventArgs.Empty);
        }
     }
   }       
}

【讨论】:

  • 我已经实现了 INPC;这就是它最初的工作方式。我会尝试依赖属性并让你知道它是否有效。
  • @JasonD 抱歉,请参阅更新,GameContainer 应该必须继承自 DependencyObject。
  • @JasonD 首先,它对您有用,因为您的Date 没有实际上 更改,只是其中一个Data members 更改了。顺便说一句,我经历过 奇怪 的事情,有时 INotifyPropertyChanged 不起作用,但 DependencyProperty 工作正常。
  • 我现在遇到的问题是我需要Locator 中的GameContainer 对象是静态的,这会造成麻烦。
  • 我得到 2 个错误,一个在 getter 上,一个在 setter 上(在 Locator 的 Container 属性上):An object reference is required for the non-static field, method, or property 'System.Windows.DependencyObject.GetValue(System.Windows.DependencyProperty)'
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-20
  • 1970-01-01
  • 2017-07-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多