TextBox Text プロパティにバインドされた文字列にテキスト ファイルをロードする TextBox とボタンを含むプロジェクトがあります。
コード: MainPage.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
}
そして私のObservableObject:
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));
}
}
ご覧のとおり、たとえば、チェックボックスと DatePicker にバインドされた「DateIsNotChecked」プロパティもあり、それは機能します。デバッグによって、「CardsList」が更新されると、「ObservableObject」の PropertyChanged イベントがバインディングを更新しないのは null と等しいためです。残念ながら、理由がわかりません。誰かが私の間違いを指摘してくれませんか?;)
ご協力いただきありがとうございます:)