WPF文本框在datatemplate中的TwoWay绑定即使在LostFocus上也不更新源

时间:2015-06-29 07:12:30

标签: wpf data-binding textbox datatemplate

我有ObservableCollection<string> Tags作为自定义对象的一部分。我将其绑定到DataTemplate,以便使用以下代码向用户显示所有标记:

<StackPanel DockPanel.Dock="Top" Margin="15,0,15,0" Orientation="Horizontal">
    <Label Content="Tags:" FontSize="14" Foreground="{StaticResource HM2LightTextBrush}"/>
    <Grid>
        <ItemsControl Name="PanelPreviewNoteTags" ItemsSource="{Binding ElementName=lbNotesQuickView, Path=SelectedItem.Tags}" Margin="3,0" Visibility="Collapsed">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <WrapPanel/>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <Border BorderThickness="1" BorderBrush="#676B6E" Margin="3,0">
                        <Label Content="{Binding .,Mode=OneWay}" Foreground="{StaticResource HM2LightTextBrush}"/>
                    </Border>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
        <ItemsControl Name="PanelEditNoteTags" ItemsSource="{Binding ElementName=lbNotesQuickView, Path=SelectedItem.Tags}" Margin="3,0" Visibility="Collapsed">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <WrapPanel/>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <Border BorderThickness="1" BorderBrush="#676B6E" Margin="3,0">
                        <StackPanel Orientation="Horizontal">
                            <TextBox Text="{Binding ., Mode=TwoWay}"/>
                            <Button Style="{StaticResource RibbonButton}" Click="ButtonRemoveTagClick" Tag="{Binding}">
                                <Image Height="16" Width="16" Source="/Poker Assistant;component/Resources/fileclose.png" />
                            </Button>
                        </StackPanel>
                    </Border>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </Grid>
</StackPanel>

添加和删除ObservableCollection中的项目按预期工作。

在代码中,我通过设置相应VisibilityPanelEditNoteTags的{​​{1}}来在编辑和查看模式之间切换。这一切都很好,也很有效。但是当我进入编辑模式并开始在PanelPreviewNoteTags中为标记键入新值时,源代码不会更新。我当然知道当我按下TextBox按钮时会发出LostFocus事件。我尝试了所有Save值,但仍然相同。

这是一个与两个控件同时绑定到同一个值相关的问题 - 来自UpdateSourceTrigger的{​​{1}}和来自Label的{​​{1}}?

我在这里缺少什么?

1 个答案:

答案 0 :(得分:1)

@Clemens感谢您快速准确的回复:)以下是工作解决方案,供将来参考。

解决方案不是使用{Binding ., Mode=TwoWay},因为正如Clemens所指出的那样,Tag无法返回源。

所以我创建了一个自定义public class Tag : INotifyPropertyChanged { private string _content; public string Content { get { return _content; } set { _content = value; OnMyPropertyChanged(() => Content); } } public Tag(string content) { Content = content; } public Tag() : this("new tag") { } public event PropertyChangedEventHandler PropertyChanged; // Raise the event that a property has changed in order to update the visual elements bound to it internal void OnPropertyChanged(string name) { PropertyChangedEventHandler handler = PropertyChanged; if (handler != null) { handler(this, new PropertyChangedEventArgs(name)); } } //CONVERTS the passed parameter to its name in string internal void OnMyPropertyChanged<T>(Expression<Func<T>> memberExpression) { MemberExpression expressionBody = (MemberExpression)memberExpression.Body; OnPropertyChanged(expressionBody.Member.Name); } public override string ToString() { return Content; } } 类:

ObservableCollection<Tag> Tags

并将其用作<TextBox Text="{Binding Content, Mode=TwoWay}" Tag="{Binding}"/> 。然后像这样绑定它

string[] array = note.Tags.Select(item => item.Content).ToArray();
note.Tags = new ObservableCollection<Tag>((array.Select(item => new Tag() { Content = item }).ToList()));

我实际上是从字符串数组列填充并保存到postgres数据库,所以我需要转换为string []和从string []转换。这些是我的转换:

any_cast