Caliburn.Micro 字典改变后不更新 ListView
Caliburn.Micro does not update ListView after dictationary changed
我正在使用 Caliburn.Micro 构建桌面 MVVM 应用程序,但在更新 ListView 时遇到问题。
这是我的模型:
public class Answer
{
public int AnswerType { get; set; }
public string CorrectAnswer { get; set; }
}
public class TestCaseConfig
{
public float MaxReactionTime { get; set; }
public List<Answer> Answers { get; set; }
}
我正在使用 ObservableDictionary 通知视图集合已更改 (http://blogs.microsoft.co.il/shimmy/2010/12/26/observabledictionarylttkey-tvaluegt-c/)
public ObservableDictionary<string, TestCaseConfig> testCaseConfigs { get; set; }
但是当我更新(在 List<Answer> Answers
中添加或删除项目)时,我的视图什么都不做
我发现这个问题是因为当我们更改集合中的某些内容时也会更改它在内存中的地址,但 Caliburn 不会对此更改做出反应并继续显示以前的列表。
这是我的 view.xaml:
<UserControl x:Class="Gillie.Barney.Views.ExaminationAnswerSetupView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:localization="clr-namespace:Gillie.Barney.Properties"
xmlns:cal="http://www.caliburnproject.org"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<UserControl.Resources>
<ResourceDictionary>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment"
Value="Stretch" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="IsSelected" Value="True"/>
</Trigger>
</Style.Triggers>
</Style>
</ResourceDictionary>
</UserControl.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="39*"/>
<RowDefinition Height="5*"/>
</Grid.RowDefinitions>
<ListView
Name="BaseListView"
Margin="10"
Grid.Row="1"
ItemsSource="{Binding testCaseConfigs}"
HorizontalContentAlignment="Center" Grid.ColumnSpan="2"
SelectedItem ="{Binding TestCasesConfigSelectedItem, Mode=TwoWay}">
<ListView.View>
<GridView>
<GridViewColumn
Header="{x:Static localization:Resources.TestCaseNameLable}"
DisplayMemberBinding="{Binding Key}" />
<GridViewColumn Header="Reaction Time">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBox Text="{Binding Value.MaxReactionTime}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Correct Answers">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<ListView
ItemsSource="{Binding Value.Answers, Mode=TwoWay}"
Grid.Column="0">
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="150"/>
<ColumnDefinition Width="150"/>
<ColumnDefinition Width="25"/>
</Grid.ColumnDefinitions>
<ComboBox
Grid.Column="0"
SelectedIndex="{Binding AnswerType}"
Margin="5,0,5,0">
<ComboBoxItem Content="{x:Static localization:Resources.ScriptsLabel}"/>
<ComboBoxItem Content="{x:Static localization:Resources.AllObjectionsLabel}"/>
<ComboBoxItem Content="{x:Static localization:Resources.QuickAnswersLabel}"/>
</ComboBox>
<TextBox
Grid.Column="1"
Text="{Binding CorrectAnswer}"/>
<Button
Grid.Column="2"
HorizontalAlignment="Center"
Width="20"
Height="20"
Margin="5,0,0,0"
cal:Message.Attach="DeleteItem($dataContext)">
<Button.Content>
<Image Source="/Resources/delete.ico"/>
</Button.Content>
</Button>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<Button
VerticalAlignment="Bottom"
Width="20" Height="20"
Grid.Column="1"
Margin="5,0,0,2"
cal:Message.Attach="AddItem()">
<Button.Content>
<Image Source="/Resources/add.ico"/>
</Button.Content>
</Button>
</Grid>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
<Button
Content="{x:Static localization:Resources.SettingsSaveButtonContent}"
Margin="10,0,10,10"
Grid.Row="2"
Grid.Column="1"
cal:Message.Attach="Save()"/>
<Button
Content="{x:Static localization:Resources.CancelButtonContent}"
Margin="10,0,10,10"
Grid.Row="2"
Grid.Column="0"
cal:Message.Attach="Cancel()"/>
</Grid>
</UserControl>
我已经有一段时间没有使用 Caliburn Micro 了,所以请对以下内容持保留态度:)
ObservableDictionary<string, TestCaseConfig>
仅监听直接在字典上的更改,这意味着当您向字典添加或删除项目时。在您的情况下,您不会这样做,而是更改字典中已有项目的某些内容。
所以,你需要的是改变你的
public List<Answer> Answers { get; set; }
到可以观察到的列表 - 例如 ObservableList<Anwer>
(或类似的名称 - 不记得 Caliburn.Micro 术语)。
我正在使用 Caliburn.Micro 构建桌面 MVVM 应用程序,但在更新 ListView 时遇到问题。
这是我的模型:
public class Answer
{
public int AnswerType { get; set; }
public string CorrectAnswer { get; set; }
}
public class TestCaseConfig
{
public float MaxReactionTime { get; set; }
public List<Answer> Answers { get; set; }
}
我正在使用 ObservableDictionary 通知视图集合已更改 (http://blogs.microsoft.co.il/shimmy/2010/12/26/observabledictionarylttkey-tvaluegt-c/)
public ObservableDictionary<string, TestCaseConfig> testCaseConfigs { get; set; }
但是当我更新(在 List<Answer> Answers
中添加或删除项目)时,我的视图什么都不做
我发现这个问题是因为当我们更改集合中的某些内容时也会更改它在内存中的地址,但 Caliburn 不会对此更改做出反应并继续显示以前的列表。
这是我的 view.xaml:
<UserControl x:Class="Gillie.Barney.Views.ExaminationAnswerSetupView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:localization="clr-namespace:Gillie.Barney.Properties"
xmlns:cal="http://www.caliburnproject.org"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<UserControl.Resources>
<ResourceDictionary>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment"
Value="Stretch" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="IsSelected" Value="True"/>
</Trigger>
</Style.Triggers>
</Style>
</ResourceDictionary>
</UserControl.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="39*"/>
<RowDefinition Height="5*"/>
</Grid.RowDefinitions>
<ListView
Name="BaseListView"
Margin="10"
Grid.Row="1"
ItemsSource="{Binding testCaseConfigs}"
HorizontalContentAlignment="Center" Grid.ColumnSpan="2"
SelectedItem ="{Binding TestCasesConfigSelectedItem, Mode=TwoWay}">
<ListView.View>
<GridView>
<GridViewColumn
Header="{x:Static localization:Resources.TestCaseNameLable}"
DisplayMemberBinding="{Binding Key}" />
<GridViewColumn Header="Reaction Time">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBox Text="{Binding Value.MaxReactionTime}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Correct Answers">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<ListView
ItemsSource="{Binding Value.Answers, Mode=TwoWay}"
Grid.Column="0">
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="150"/>
<ColumnDefinition Width="150"/>
<ColumnDefinition Width="25"/>
</Grid.ColumnDefinitions>
<ComboBox
Grid.Column="0"
SelectedIndex="{Binding AnswerType}"
Margin="5,0,5,0">
<ComboBoxItem Content="{x:Static localization:Resources.ScriptsLabel}"/>
<ComboBoxItem Content="{x:Static localization:Resources.AllObjectionsLabel}"/>
<ComboBoxItem Content="{x:Static localization:Resources.QuickAnswersLabel}"/>
</ComboBox>
<TextBox
Grid.Column="1"
Text="{Binding CorrectAnswer}"/>
<Button
Grid.Column="2"
HorizontalAlignment="Center"
Width="20"
Height="20"
Margin="5,0,0,0"
cal:Message.Attach="DeleteItem($dataContext)">
<Button.Content>
<Image Source="/Resources/delete.ico"/>
</Button.Content>
</Button>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<Button
VerticalAlignment="Bottom"
Width="20" Height="20"
Grid.Column="1"
Margin="5,0,0,2"
cal:Message.Attach="AddItem()">
<Button.Content>
<Image Source="/Resources/add.ico"/>
</Button.Content>
</Button>
</Grid>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
<Button
Content="{x:Static localization:Resources.SettingsSaveButtonContent}"
Margin="10,0,10,10"
Grid.Row="2"
Grid.Column="1"
cal:Message.Attach="Save()"/>
<Button
Content="{x:Static localization:Resources.CancelButtonContent}"
Margin="10,0,10,10"
Grid.Row="2"
Grid.Column="0"
cal:Message.Attach="Cancel()"/>
</Grid>
</UserControl>
我已经有一段时间没有使用 Caliburn Micro 了,所以请对以下内容持保留态度:)
ObservableDictionary<string, TestCaseConfig>
仅监听直接在字典上的更改,这意味着当您向字典添加或删除项目时。在您的情况下,您不会这样做,而是更改字典中已有项目的某些内容。
所以,你需要的是改变你的
public List<Answer> Answers { get; set; }
到可以观察到的列表 - 例如 ObservableList<Anwer>
(或类似的名称 - 不记得 Caliburn.Micro 术语)。