Silverlight:TextBox 未更新,PropertyChangedEventHandler 为空

本文关键字:PropertyChangedEventHandler 为空 更新 TextBox Silverlight | 更新日期: 2023-09-27 18:35:42

我有一个项目,其中包括文本框和按钮,它将文本文件加载到绑定到文本框文本属性的字符串中。

法典:在我的主页中.xaml

<Grid Grid.Column="0" Grid.Row="1">
 <Grid.DataContext>
  <local:ViewModel/>
 </Grid.DataContext>
<Grid.RowDefinitions>
 <RowDefinition Height="25"/>
 <RowDefinition/>
 <RowDefinition Height="30"/>
</Grid.RowDefinitions>
 <TextBox Grid.Row="1" Margin="5,5,5,5" VerticalScrollBarVisibility="Visible" AcceptsReturn="True" Text="{Binding CardsList, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
 <StackPanel Grid.Row="2" Orientation="Horizontal" Margin="5,0,0,0" >
  <Button Content="Wczytaj Plik" Command="{Binding LoadTextFile}"/>
  <Button Content="Wyczyść Listę"></Button>
 </StackPanel>
</Grid>

我的视图模型:

public class ViewModel : ObservableObject
{
    private static bool _dateIsNotChecked;
    private static string _cardsList;        
    public static ICommand LoadTextFile { get; set; }
    private OpenFileDialog textOpenFileDialog;
    #region Properties
    public string CardsList
    {
        get
        {
            return _cardsList;
        }
        set
        {
            _cardsList = value;
            RaisePropertyChanged("_cardsList"); //It was CardList - still doesn't work
        }
    }
    public bool DateIsNotChecked
    {
        get
        {
            return _dateIsNotChecked;
        }
    }
    public bool DateIsChecked
    {
        get
        {
            return !_dateIsNotChecked;
        }
        set
        {
            _dateIsNotChecked = !value;
            RaisePropertyChanged("DateIsNotChecked");
        }
    }
    #endregion Properties
    public ViewModel()
    {
        if (CardsList == null)
        {
            CardsList = "";
            _dateIsNotChecked = false;
            LoadTextFile=new DelegateCommand(LoadTextFileExecute, CanLoadTextFileExecute);
            emmDialog = new SaveFileDialog { Filter = "Emm Files | *.emm", DefaultExt = "emm" };
            textOpenFileDialog = new OpenFileDialog{Filter="TXT Files|*.txt"};
        }
    }

    #region Commands 
    void CreateEmmFileExecute(object param)
    {
        var emmFileText = new EmmCreator(Message, Duration, Date, RepeatCount, RepeatDuration, CardsList.Split(new string[] {"'r'n"}, StringSplitOptions.RemoveEmptyEntries).ToList());
        if (emmDialog.ShowDialog() != true) return;
        using (var temp = new StreamWriter(emmDialog.OpenFile()))
        {
                temp.Write(emmFileText.EmmFile);
        }
    }
    bool CanCreateEmmFileExecute(object param)
    {
        return true;
    }
    void LoadTextFileExecute(object param)
    {
        //CardsList = "2";
        if (textOpenFileDialog.ShowDialog() != true)
            return;
        using (var temp = new StreamReader(textOpenFileDialog.File.OpenRead()))
        {
            CardsList = CardsList + temp.ReadToEnd();
        }
    }
    bool CanLoadTextFileExecute(object param)
    {
        return true;
    }

    #endregion Commands

}

委托命令:

public class DelegateCommand : ICommand
    {
        /// <summary>
        /// Occurs when changes occur that affect whether the command should execute.
        /// </summary>
        public event EventHandler CanExecuteChanged;
        Func<object, bool> canExecute;
        Action<object> executeAction;
        bool canExecuteCache;
        /// <summary>
        /// Initializes a new instance of the <see cref="DelegateCommand"/> class.
        /// </summary>
        /// <param name="executeAction">The execute action.</param>
        /// <param name="canExecute">The can execute.</param>
        public DelegateCommand(Action<object> executeAction,
                               Func<object, bool> canExecute)
        {
            this.executeAction = executeAction;
            this.canExecute = canExecute;
        }
        #region ICommand Members
        /// <summary>
        /// Defines the method that determines whether the command 
        /// can execute in its current state.
        /// </summary>
        /// <param name="parameter">
        /// Data used by the command. 
        /// If the command does not require data to be passed,
        /// this object can be set to null.
        /// </param>
        /// <returns>
        /// true if this command can be executed; otherwise, false.
        /// </returns>
        public bool CanExecute(object parameter)
        {
            bool tempCanExecute = canExecute(parameter);
            if (canExecuteCache != tempCanExecute)
            {
                canExecuteCache = tempCanExecute;
                if (CanExecuteChanged != null)
                {
                    CanExecuteChanged(this, new EventArgs());
                }
            }
            return canExecuteCache;
        }
        /// <summary>
        /// Defines the method to be called when the command is invoked.
        /// </summary>
        /// <param name="parameter">
        /// Data used by the command. 
        /// If the command does not require data to be passed, 
        /// this object can be set to null.
        /// </param>
        public void Execute(object parameter)
        {
            executeAction(parameter);
        }
        #endregion
    }

还有我的可观察对象:

public abstract class ObservableObject : INotifyPropertyChanged
    {

        public  event PropertyChangedEventHandler PropertyChanged;
        protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
        {
            var handler = this.PropertyChanged;
            if (handler != null)
            {
                handler(this, e);
            }
        }
        protected void RaisePropertyChanged<T>(Expression<Func<T>> propertyExpresssion)
        {
            var propertyName = PropertySupport.ExtractPropertyName(propertyExpresssion);
            this.RaisePropertyChanged(propertyName);
        }
        protected void RaisePropertyChanged(string propertyName)
        {
            //VerifyPropertyName(propertyName);
            OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
        }
    }

如您所见,我还有一个"DateIsNotChecked"属性,该属性绑定到复选框和日期选择器并且它可以工作。通过调试,我得出的结论是,当"CardsList"更新时,"ObservableObject"中的PropertyChanged事件等于null,这就是它不更新绑定的原因。不幸的是,我不知道为什么,有人可以指出我的错误吗;)?

感谢您的帮助:)

Silverlight:TextBox 未更新,PropertyChangedEventHandler 为空

尝试:

RaisePropertyChanged("CardsList"); 

必须在文本框绑定到的属性上引发更改的属性。 换句话说,是公共财产,而不是私人支持者。

此外,请尝试在文本框中设置 TextWrapping = TextWrapping.Wrap。

接下来,尝试调试:将断点设置为

LoadTextFileExecute

并逐步完成它并确保它正在执行您想要的一切。

此外,请尝试在 CardsList 的设置器上放置一个断点,以确保它按预期设置。

格雷格