我是C#和WPF的新手,已经完成了编程报警的任务。现在我遇到了问题,我必须在关闭主窗口时将设置时间保存到文本文件中。
时间存储在Reminder类型的ObservableCollection中,这是我自己编写的类,并将警报的时间和名称存储为字符串。
public override string ToString()
{
return ReminderName + " " + ReminderTime.ToString("HH:mm");
}
我的保存功能如下:
...
public RelayCommand<object> SaveAllTimes { get; set; }
...
public MainWindowModel()
{
...
SaveAllTimes = new RelayCommand<object>(SaveReminders, CanSaveReminders);
...
}
private void SaveReminders(object sender)
{
StreamWriter writer = new StreamWriter("time.txt");
foreach (Reminder time in Reminders)
{
writer.WriteLine(time.ToString());
}
}
现在我如何将视图绑定到此函数,它是在用户关闭它时执行的?
我的观点如下:
<Window x:Class="Wecker1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Wecker1"
Height="350"
Width="310" >
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="3*" />
<RowDefinition Height="1*" />
</Grid.RowDefinitions>
<ListBox Name="Liste" ItemsSource="{Binding Reminders}" Margin="10" Grid.Row="0">
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox Content="{Binding}" IsChecked="{Binding Active}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<Button Command="{Binding SaveTime}" Content="Add Reminder" Margin="10" Grid.Column="1"/>
<Button Margin="10" Content="Stop" Command="{Binding DeleteTime}"
CommandParameter="{Binding ElementName=Liste,Path=SelectedItem}" />
</Grid>
</Grid>
</Window>
答案 0 :(得分:0)
在代码的某处,您正在创建View和ViewModel。从我的观点来看(这部分肯定是基于意见的)你应该在那里实现你的退出代码,因为你保存的数据是在流程的最后,而不是视图的结尾。运行MainWindow时,可以调用viewmodel方法来保存所有相关数据。
如果你想在关闭视图而不是结束程序时拥有它,你可以走两条路:黑暗的一面,为窗口编写一个代码隐藏的OnClose处理程序。不要告诉任何我说过的人。这不是WPF风格。或者通过为窗口实现Close-Behavior来获得正确的路径。这对于单个帖子来说太宽泛了,你应该查找WPF,View和Behavior,你会发现很多不同行为的教程。
答案 1 :(得分:0)
您可以使用互动功能将Closing
事件绑定到Command
,如下所示
<Window xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Closing">
<i:InvokeCommandAction Command="{Binding SaveAllTimes }"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Window>
答案 2 :(得分:0)
这是我使用纯MVVM的方法,不依赖于任何其他提供程序
XAML
<Window x:Class="CSharpWPF.ViewModel"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:l="clr-namespace:CSharpWPF"
l:MyEventHandler.ClosingCommand="{Binding SaveAllTimes}">
</Window>
MyEventHandler类
namespace CSharpWPF
{
public class MyEventHandler
{
public static ICommand GetClosingCommand(DependencyObject obj)
{
return (ICommand)obj.GetValue(ClosingCommandProperty);
}
public static void SetClosingCommand(DependencyObject obj, ICommand value)
{
obj.SetValue(ClosingCommandProperty, value);
}
// Using a DependencyProperty as the backing store for ClosingCommand. This enables animation, styling, binding, etc...
public static readonly DependencyProperty ClosingCommandProperty =
DependencyProperty.RegisterAttached("ClosingCommand", typeof(ICommand), typeof(MyEventHandler), new PropertyMetadata(OnClosingCommandChanged));
private static void OnClosingCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
Window window = d as Window;
window.Closing += (s, ee) => GetClosingCommand(d).Execute(ee);
}
}
}
所以整个想法是通过Attached Properties
将事件路由到绑定命令,您可以根据需要创建更多处理程序