我基于Microsoft的官方示例创建MasterDetail ListView:MasterDetail ListView UWP示例
我已将其调整为适合我的情况,因为我希望用户可以直接从ListView编辑选定的项目。但是我遇到一个奇怪的见解:
我的ListView的XAML是这样的:
<!-- Master : List of Feedbacks -->
<ListView
x:Name="MasterListViewFeedbacks"
Grid.Row="1"
ItemContainerTransitions="{x:Null}"
ItemTemplate="{StaticResource MasterListViewFeedbacksItemTemplate}"
IsItemClickEnabled="True"
ItemsSource="{Binding CarForm.feedback_comments}"
SelectedItem="{Binding SelectedFeedback, Mode=TwoWay}">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</ListView.ItemContainerStyle>
<ListView.FooterTemplate>
<DataTemplate>
<CommandBar Background="White">
<CommandBar.Content>
<StackPanel Orientation="Horizontal">
<AppBarButton Icon="Add" Label="Add Feedback"
Command="{Binding AddItemFeedbacksCommand}" />
<AppBarButton Icon="Delete" Label="Delete Feedback"
Command="{Binding RemoveItemFeedbacksCommand}" />
</StackPanel>
</CommandBar.Content>
</CommandBar>
</DataTemplate>
</ListView.FooterTemplate>
</ListView>
ListView的ItemTemplate的XAML是:
<DataTemplate x:Key="MasterListViewFeedbacksItemTemplate" x:DataType="models:Feedback_Comments">
<StackPanel Margin="0,11,0,13"
Orientation="Horizontal">
<TextBlock Text="{x:Bind creator }"
Style="{ThemeResource BaseTextBlockStyle}" />
<TextBlock Text=" - " />
<TextBlock Text="{x:Bind comment_date }"
Margin="12,1,0,0" />
</StackPanel>
</DataTemplate>
Details容器的XAML如下所示:
<!-- Detail : Selected Feedback -->
<ContentPresenter
x:Name="DetailFeedbackContentPresenter"
Grid.Column="1"
Grid.RowSpan="2"
BorderThickness="1,0,0,0"
Padding="24,0"
BorderBrush="{ThemeResource SystemControlForegroundBaseLowBrush}"
Content="{x:Bind MasterListViewFeedbacks.SelectedItem, Mode=OneWay}">
<ContentPresenter.ContentTemplate>
<DataTemplate x:DataType="models:Feedback_Comments">
<StackPanel Visibility="{Binding FeedbacksCnt, Converter={StaticResource CountToVisibilityConverter}}">
<TextBox Text="{Binding creator, Mode=TwoWay}" />
<DatePicker Date="{Binding comment_date, Converter={StaticResource DateTimeToDateTimeOffsetConverter}, Mode=TwoWay}"/>
<TextBox TextWrapping="Wrap" AcceptsReturn="True" IsSpellCheckEnabled="True"
Text="{Binding comment, Mode=TwoWay}" />
</StackPanel>
</DataTemplate>
</ContentPresenter.ContentTemplate>
<ContentPresenter.ContentTransitions>
<!-- Empty by default. See MasterListView_ItemClick -->
<TransitionCollection />
</ContentPresenter.ContentTransitions>
</ContentPresenter>
“ CarForm ”是我的ViewModel的主要对象。每个CarForm都包含“ Feedback_Comments ”列表。
因此,在我的ViewModel中,当我添加一个新注释时,我将执行以下操作:
private void AddItemFeedbacks()
{
FeedbacksCnt++;
CarForm.feedback_comments.Add(new Feedback_Comments()
{
sequence = FeedbacksCnt,
creator_id = user_id,
_creator = username,
comment_date = DateTime.Now
});
SelectedFeedback = CarForm.feedback_comments[CarForm.feedback_comments.Count - 1];
}
=>在添加之前对已在Feedback_Comment中进行编辑的更改进行了很好的保存
当用户选择一个现有的Feedback_Comment时,我什么也不做:这直接由XAML管理。
=>在“ Feedback_Comment”中所做的更改(以前选择“ annoter”之一进行编辑)不会保留
=>您有什么解释吗?
仅当失去焦点时,属性的TwoWay
绑定Text
才会更新TextBox
。但是,当您在列表中选择其他项目时,的内容TextBox
不再绑定到原始项目,因此不会更新。
要在每次Text
内容更改时触发更新,以使更改立即反映出来,请将UpdateSourceTrigger
设置设置为PropertyChanged
:
<TextBox Text="{Binding comment, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
为了确保所做的更改被重新整理到包括列表在内的所有位置,您将需要做两件事。
首先,您feedback_comments
的类型是ObservableCollection<Feedback_Comments>
。这样可确保添加和删除的项目已从中添加和删除ListView
。
其次,Feedback_Comments
该类必须实现INotifyPropertyChanged
接口。需要此接口来使用户界面知道数据绑定对象属性中的更改。
实现此接口非常简单,例如在MSDN上进行了描述。
快速解决方案如下所示:
public class Feedback_Comments : INotifyPropertyChanged
{
// your code
//INotifyPropertyChanged implementation
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged( [ CallerMemberName ]string propertyName = "" )
{
PropertyChanged?.Invoke( this, new PropertyChangedEventArgs( propertyName ) );
}
}
现在,OnPropertyChanged();
在设置值之后,从每个属性设置器调用:
private string _comment = "";
public string Comment
{
get
{
return _comment;
}
set
{
_comment = value;
OnPropertyChanged();
}
}
请注意,该[CallerMemberName]
属性告诉编译器用调用者的名称替换参数-在这种情况下,属性的名称正是您所需要的。
另请注意,在这种情况下,您不能使用简单的自动属性(因为您需要调用该OnPropertyChanged
方法。
最后,作为一个小建议,我看到您正在使用类似C ++的命名约定,但这种命名约定不太适合C#领域。看一下推荐的C#命名约定,以提高代码的可读性:-)。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句