Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 关闭主窗口时将ObservableCollection保存到文本文件_C#_Wpf_Mvvm - Fatal编程技术网

C# 关闭主窗口时将ObservableCollection保存到文本文件

C# 关闭主窗口时将ObservableCollection保存到文本文件,c#,wpf,mvvm,C#,Wpf,Mvvm,我是C#和WPF的新手,我已经接到了编写警报程序的任务。现在我遇到了一个问题,当关闭主窗口时,我必须将设置的时间保存到一个文本文件中 时间存储在类型为Reminder的ObservableCollection中,这是我自己编写的一个类,它将时间和报警名称存储为字符串 public override string ToString() { return ReminderName + " " + ReminderTime.ToString("HH:mm

我是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>
。。。
public RelayCommand SaveAllTimes{get;set;}
...
公共主窗口模型()
{
...
SaveAllTimes=新的RelayCommand(保存提醒,可保存提醒);
...
}
私有作废保存提醒(对象发送者)
{
StreamWriter=新的StreamWriter(“time.txt”);
foreach(提醒中的提醒时间)
{
WriteLine(time.ToString());
}
}
现在,我如何将视图绑定到这个函数,即当用户关闭它时执行它

我的观点是这样的:

...
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>

在代码的某个地方,您正在创建视图和视图模型。从我的观点来看(这一部分当然是基于观点的),您应该在那里实现您的On-Exit代码,因为您的数据保存在流程的末尾,而不是视图的末尾。当主窗口运行时,可以调用viewmodel方法来保存它的所有相关数据


如果您确实希望在关闭视图而不是结束程序时使用它,那么可以通过在窗口的OnClose处理程序后面编写代码,走两条路:黑暗面。不要告诉任何人我是这么说的。那不是WPF风格。或者通过实现窗口的关闭行为来选择正确的路径。这对于一篇文章来说太宽泛了,你应该查找WPF、View和Behavior,你会找到许多不同行为的教程。

你可以使用交互性将
关闭
事件绑定到你的
命令中,如下所示

<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>

以下是我使用纯MVVM的方法,不依赖于任何其他提供商

xaml

因此,整个想法是通过
附加属性
将事件路由到绑定的命令,您可以根据需要创建更多的处理程序