Open houihoui opened 3 years ago
Hi,
I've build a sample based on your description. When I modify the "Name" TextBox and click the next Tab, I can see a LostFocus output. Then clicking back on first Tab shows the modified text in the "Name" TextBox. Here's my sample. Can you try it out and confirm ? I used the latest v4.0.2 of Toolkit from NuGet.
MainWindow.xaml:
`
Hi, thanks for the answer.
I confirm that your sample is indeed working (the LostFocus event fires when you change tabs), but the viewmodel you are using is a usercontrol.
For obvious separation reasons, my vm is a simple object which implements INotifyPropertyChanged like this:
public class DocumentViewModel : INotifyPropertyChanged
{
public DocumentViewModel()
{
}
string docNameValue;
public string DocName
{
get
{
return this.docNameValue;
}
set
{
if (value != this.docNameValue)
{
this.docNameValue = value;
NotifyPropertyChanged();
}
}
}
string docTitleValue;
public string DocTitle
{
get
{
return this.docTitleValue;
}
set
{
if (value != this.docTitleValue)
{
this.docTitleValue = value;
NotifyPropertyChanged();
}
}
}
int lengthValue;
public int Length
{
get
{
return this.lengthValue;
}
set
{
if (value != this.lengthValue)
{
this.lengthValue = value;
NotifyPropertyChanged();
}
}
}
bool isPdf;
public bool IsPdf
{
get
{
return this.isPdf;
}
set
{
if (value != this.isPdf)
{
this.isPdf = value;
NotifyPropertyChanged();
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
And when you bind it via the Documents property of the main vm, i have a LayoutItemTemplateSelector that returns the UserControl (here it's DocCtrl)
<ResourceDictionary>
<DataTemplate x:Key="DocDataTemplate">
<local:DocCtrl/>
</DataTemplate>
<local:TemplateSelector x:Key="DockingManagerTemplateSelector"
DocumentTemplate="{StaticResource DocDataTemplate}"/>
</ResourceDictionary>
<xcad:DockingManager DocumentsSource="{Binding Documents}"
LayoutItemTemplateSelector="{StaticResource DockingManagerTemplateSelector}">
<xcad:DockingManager.DocumentHeaderTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Content.DocTitle}" />
</StackPanel>
</DataTemplate>
</xcad:DockingManager.DocumentHeaderTemplate>
public class TemplateSelector : DataTemplateSelector
{
public TemplateSelector() { }
public DataTemplate DocumentTemplate { get; set; }
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
//check if the item is an instance of DocumentViewModel
if (item is DocumentViewModel)
return DocumentTemplate;
//delegate the call to base class
return base.SelectTemplate(item, container);
}
}
It's not very usefull in that case since there is just one type of vm, but in my real app, it is. In that case the LostFocus event is fired too late when you change tabs (when it is fired, there isn't any datacontext attached to it). The full project is in attachment.
Hi, Thank you for the clarification. We'll need to investigate on this.
I invite you to test your sample with a standard TabControl. The same thing happens. This could be a TabControl problem....or in the way your sample is built:
<TabControl ItemsSource="{Binding Documents}" ContentTemplateSelector="{StaticResource DockingManagerTemplateSelector}" SelectedIndex="0"/>
You're right, the same thing happens in a standard tabcontrol! I can't imagine what could be causing this in my sample since it is really really simple, on the other hand it would mean that this bug is in wpf framework since 2006?
Hi, did a little digging for this problem, if the subject is interesting for anyone. It turns out that "The problem is not that it is not changing focus on the form, the problem is that it is setting the DataContext on the view to null before it changes focus, so the binding can no longer write the current value to the view model." as it is said in that link: https://groups.google.com/g/wpf-disciples/c/HKUU61A5l74?pli=1 this problem must be solved by implementing your own derived tabcontrol since it hasn't been adressed by MS
Hi, I am using DockingManager following a mvvm pattern, like this:
Documents property is in my main vm :
i have a userctrl as datatemplate for each DocumentViewModel binded to properties in a LostFocus mode:
giving something like: i change the first textbox content, adding any char: then i click on the other tab: if i want to comme back to the first tab, my changes have disapeared!
however if i change the text in the first textbox then i click on the other textbox just below, firing the LostFocus event and updating the source, the changes remain as expected, so i think there's a bug with the LostFocus event when clicking directly on other tab.