簡體   English   中英

與INotifyPropertyChanged的綁定仍然不起作用

[英]Binding with INotifyPropertyChanged Still Doesn't Work

嘗試了很多東西,仍然無法正常工作。 綁定兩個TextBlocks無效。 使用INotifyPropertyChanged接口非常類似於此代碼 ,但無濟於事。

碼:

MainWindow.xaml

<Window
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:ClockWatcher" xmlns:System="clr-namespace:System;assembly=mscorlib"
        x:Name="clockWatcherWindow"
        x:Class="ClockWatcher.MainWindow"
        Title="Clock Watcher" Height="554" Width="949"
    KeyDown="KeysDown" Focusable="True" Closing="SaveSession"
    DataContext="{Binding SM, RelativeSource={RelativeSource Self}}">
    <TextBlock x:Name="programStartBlock" Text="{Binding StartTime, BindsDirectlyToSource=True, FallbackValue=Binding sucks so much!!!,  StringFormat=ProgramStarted: \{0\}, TargetNullValue=This thing is null}" Padding="{DynamicResource labelPadding}" FontSize="{DynamicResource fontSize}"/>
    <TextBlock x:Name="totalTimeLabel" Text="{Binding SM.currentSession.TotalTime, StringFormat=Total Time: \{0\}}" Padding="{DynamicResource labelPadding}" FontSize="{DynamicResource fontSize}"/>
</Window>

MainWindow.xaml.cs

public partial class MainWindow : Window
{
    private const string SESSION_FILENAME = "SessionFiles.xml";

    /// <summary>
    /// Represents, during selection mode, which TimeEntry is currently selected.
    /// </summary>

    public SessionManager SM { get; private set; }

    public MainWindow()
    {
        InitializeComponent();
        SM = new SessionManager();
        SM.newAddedCommentEvent += currentTimeEntry_newComment;
        SM.timeEntryDeletedEvent += currentTimeEntry_delete;
        SM.commentEntryDeletedEvent += entry_delete;
    }
}

SessionManager.cs

public class SessionManager : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        [NonSerialized]
        private DateTime _dtStartTime;
        private Session current_session;
        #region Properties

        public DateTime StartTime
        {
            get
            {
                return _dtStartTime;
            }
            private set
            {
                if (_dtStartTime != value)
                {
                    _dtStartTime = value;
                    OnPropertyChanged("StartTime");
                }
            }
        }


 public Session CurrentSession
    {
        get
        {
            return current_session;
        }
        set
        {
            if (current_session != value)
            {
                OnPropertyChanged("CurrentSession");
                current_session = value;
            }
        }
    }
        #endregion

        public SessionManager()
        {
            _dtStartTime = DateTime.Now;
        }

        private void OnPropertyChanged([CallerMemberName] string member_name = "")
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(member_name));
            }
        }
    }

Session.cs

public class Session : INotifyPropertyChanged
    {
        private TimeSpan total_time;
        public DateTime creationDate { get; private set; }
        public event PropertyChangedEventHandler PropertyChanged;


        public TimeSpan TotalTime
        {
            get
            {
                return total_time;
            }
            set
            {
                if (total_time != value)
                {
                    OnPropertyChanged("TotalTime");
                    total_time = value;
                }
            }
        }

        public Session()
        {
            creationDate = DateTime.Now;
        }

        private void OnPropertyChanged([CallerMemberName] string member_name = "")
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(member_name));
            }
        }
    }
  1. 在第一個TextBlock中,僅寫入StartTime,而不是SM.StartTime。

  2. 從第一個TB中刪除ElementName。

  3. 將CurrentSession設為公共屬性,您的currentSession現在是私有的。

  4. 在您的SessionManager ctor中, current_session = new Session();

  5. 從XAML中刪除DataContext,使用this.DataContext = SM; 在您的窗口構造器中。

  6. 如果要在XAML中使用DataContext,

     <Window.DataContext> <local:SessionManager /> </Window.DataContext> 

標有正確答案的絕對是執行此操作的更好方法,但我只是想回答更多詳細信息,以解釋您發布的內容為何無效的原因。

問題是,當您在MainWindow.xaml中編寫DataContext={Binding SM, RelativeSource={RelativeSource Self}時,在行SM = new SessionManager();之前對綁定進行了評估SM = new SessionManager(); 是在MainWindow.xaml.cs構造函數中執行的。

如果將SM的獲取程序更改為:

public SessionManager SM
{
    get { return new SessionManager();}
}

這基本上可以確保WPF在評估您的綁定時,將為您的SM屬性獲得一個實際對象,而不是null。

只是認為這可能有助於下次理解並減少挫敗感:)。 問問題的方式,從技術上講,您需要在MainWindow類上實現INotifyPropertyChanged,這是一個很大的禁忌。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM