问题
I have an ObservableCollection<string> Tags
as part of a custom object. I bind it to a DataTemplate
in order to show all tags to the user with the following code:
<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>
Adding and removing items from the ObservableCollection
works as expected.
In code I switch between edit and view mode by setting the Visibility
of the corresponding PanelEditNoteTags
and PanelPreviewNoteTags
. This all good and working. But when I enter the edit mode and start typing new values for the tags in the TextBox
the source doesn't get updated. I certainly know that the LostFocus
event is raised when I press my Save
button. I tried all UpdateSourceTrigger
values, still the same.
Is it a problem related to two controls binding at the same time to the same value - the Label
from PanelPreviewNoteTags
and the TextBox
from PanelEditNoteTags
?
What am I missing here?
回答1:
@Clemens Thank you for the quick and accurate response :) Following is the working solution for future reference.
The solution is not to use ObservableCollection<string> Tags
because as pointed by Clemens the {Binding ., Mode=TwoWay}
does not work back to the source.
So I created a custom Tag
class:
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;
}
}
And use it as ObservableCollection<Tag> Tags
. Then bind to it like so
<TextBox Text="{Binding Content, Mode=TwoWay}" Tag="{Binding}"/>
I actually populate from and save to postgres database in a string array column, so I need to convert to and from string[]. These are my conversions:
string[] array = note.Tags.Select(item => item.Content).ToArray();
note.Tags = new ObservableCollection<Tag>((array.Select(item => new Tag() { Content = item }).ToList()));
来源:https://stackoverflow.com/questions/31109776/wpf-textbox-twoway-binding-in-datatemplate-not-updating-the-source-even-on-lostf