WPF Control теряет фокус при нажатии на вкладку

На вкладке управления у меня есть несколько вкладок, на одной из вкладок есть текстовое поле в контенте.

Это текстовое поле ограничено содержимым с помощью простого Path=PropertyName и UpdateSourceTrigger=LostFocus. Причина, по которой я использую LostFocus, заключается в том, что я перехватываю событие "Потерянный фокус" текстового поля и, возможно, переформатирую текст. Это текстовое поле "время", и если они вводят "0900", я хочу переформатировать в "09:00". Эта часть прекрасно работает, когда я нажимаю клавишу табуляции, чтобы перейти к следующему элементу управления, но если я набираю "0900", затем нажимаю на одну из других вкладок, я нажимаю потерянный фокус и переформатирую значение в текстовом поле, НО привязка никогда не вызывается для обновления моего объекта. Когда я возвращаюсь на вкладку, значение не отображается (или сбрасывается на исходное значение объекта)

Есть идеи, почему текстовое поле не вызывает обновление Binding при смене вкладки?

Примечание: это также происходит с обычным текстовым полем, которое подключается к событию потерянного фокуса. Кажется, что-то связано с нажатием на вкладку.

[[Добавлен код]] Дополнительные примечания: 1. Я динамически создаю вкладки и элементы управления на вкладке (не уверен, имеет ли это какое-то отношение к этому или нет) 2. Я использую библиотеки Prism

MainWindow Xaml

<Window.Resources>
    <DataTemplate DataType="{x:Type ctrls:myTextBoxDef}">
        <Grid Width="300">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto" MinWidth="100" />
                <ColumnDefinition Width="*" />
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="28" />
            </Grid.RowDefinitions>
            <TextBlock Grid.Column="0"
                   HorizontalAlignment="Stretch"
                   VerticalAlignment="Center"
                   Text="{Binding LabelText}" />

            <TextBox Grid.Column="1"
                 HorizontalAlignment="Stretch"
                 VerticalAlignment="Center"
                 Text="{Binding DocValue,
                                Mode=TwoWay,
                                ValidatesOnDataErrors=True,
                                UpdateSourceTrigger=LostFocus}"
                         />
        </Grid>
    </DataTemplate>
</Window.Resources>


<Grid>
    <TabControl HorizontalAlignment="Stretch"
                VerticalAlignment="Stretch"
                HorizontalContentAlignment="Stretch"
                VerticalContentAlignment="Stretch"
                IsTabStop="False"                 
                ItemsSource="{Binding Tabs, Mode=OneWay}"
                SelectedItem="{Binding SelectedTab,
                                Mode=TwoWay,
                                NotifyOnSourceUpdated=True}"
                >
        <TabControl.ItemTemplate>
            <DataTemplate>
                <Grid>  
                    <TextBlock Margin="18,14,22,0"                                       
                               Text="{Binding HeaderText}" />
                </Grid>
            </DataTemplate>
        </TabControl.ItemTemplate>
        <!--  Content  -->
        <TabControl.ContentTemplate>
            <DataTemplate>
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto" />
                        <ColumnDefinition Width="Auto" />
                    </Grid.ColumnDefinitions>

                    <AdornerDecorator Grid.Column="0">
                        <ItemsControl Grid.Column="0"
                                          HorizontalAlignment="Stretch"
                                          VerticalAlignment="Stretch"
                                          IsTabStop="False"
                                          ItemsSource="{Binding Controls,
                                                                Mode=OneWay}">
                            <ItemsControl.ItemsPanel>
                                <ItemsPanelTemplate>
                                    <WrapPanel Grid.Column="0"
                                                   Margin="10,5,0,0"
                                                   HorizontalAlignment="Stretch"
                                                   VerticalAlignment="Stretch"
                                                   Orientation="Vertical" />
                                </ItemsPanelTemplate>
                            </ItemsControl.ItemsPanel>
                        </ItemsControl>
                    </AdornerDecorator>
                    </Grid>
                </DataTemplate>
            </TabControl.ContentTemplate>
        </TabControl>
    </Grid>
</Window>

Код главного окна позади

public partial class MainWindow : Window
{
    private DataContextObject obj = new DataContextObject();
    public MainWindow()
    {
        InitializeComponent();

        myTextBoxDef txt1 = new myTextBoxDef(obj, "Textbox 1", "TAB1TextBox1");
        myTextBoxDef txt1b = new myTextBoxDef(obj, "Textbox 1 value", "TAB1TextBox1");

        myTextBoxDef txt2 = new myTextBoxDef(obj, "Textbox 2", "TAB1TextBox2");
        myTextBoxDef txt2b = new myTextBoxDef(obj, "Textbox 2 value", "TAB1TextBox2");

        obj.Tabs.Add(new myTabDef("Tab 1", new ObservableCollection<myTextBoxDef>() { txt1, txt2 }));
        obj.Tabs.Add(new myTabDef("Tab 2", new ObservableCollection<myTextBoxDef>() { txt1b, txt2b }));

        obj.SelectedTab = obj.Tabs[0];

        this.DataContext = obj;
    }
}

Поддерживающие объекты

public class DataContextObject : NotificationObject
{
    List<myTabDef> _tabs = new List<myTabDef>();
    public List<myTabDef> Tabs
    {
        get
        {
            return _tabs;
        }
    }

    private myTabDef _item;
    public myTabDef SelectedTab
    {
        get
        { return _item; }
        set
        {
            _item = value;
            this.RaisePropertyChanged("SelectedItem");
        }
    }

    private string _txt1 = "";
    public string TAB1TextBox1
    {
        get { return _txt1; }
        set
        {
            _txt1 = value;
            this.RaisePropertyChanged("TAB1TextBox1");
        }
    }

    private string _txt2 = "";
    public string TAB1TextBox2
    {
        get { return _txt2; }
        set
        {
            _txt2 = value;
            this.RaisePropertyChanged("TAB1TextBox2");
        }
    }

    private string _txt3 = "";
    public string TAB2TextBox1
    {
        get { return _txt3; }
        set
        {
            _txt3 = value;
            this.RaisePropertyChanged("TAB2TextBox1");
        }
    }
}

public class myTabDef
{
    public myTabDef(string tabText, ObservableCollection<myTextBoxDef> controls)
    {
        HeaderText = tabText;
        _left = controls;
    }

    public string HeaderText { get; set; }

    private ObservableCollection<myTextBoxDef> _left = new ObservableCollection<myTextBoxDef>();
    public ObservableCollection<myTextBoxDef> Controls
    {
        get
        {
            return _left;
        }
    }
}

public class myTextBoxDef : NotificationObject
{
    public myTextBoxDef(NotificationObject bound, string label, string bindingPath)
    {
        LabelText = label;
        Path = bindingPath;
        BoundObject = bound;

        BoundObject.PropertyChanged += BoundObject_PropertyChanged;
    }

    public string LabelText
    {
        get;
        set;
    }

    public NotificationObject BoundObject
    {
        get;
        set;
    }

    public string DocValue
    {
        get
        {
            return PropInfo.GetValue(BoundObject, null) as string;
        }
        set
        {
            PropInfo.SetValue(BoundObject, value, null);
        }
    }

    protected virtual void BoundObject_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
    {
        if (e.PropertyName.Equals(Path))
        {
            this.RaisePropertyChanged("DocValue");
        }
    }

    public string Path
    {
        get;
        set;
    }

    private PropertyInfo pi = null;
    protected PropertyInfo PropInfo
    {
        get
        {
            if (pi == null && BoundObject != null && !string.IsNullOrEmpty(Path))
            {
                PropertyInfo[] properties = BoundObject.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);

                pi = properties.Where((prop) => string.Compare(prop.Name, Path, true) == 0).FirstOrDefault();
            }

            return pi;
        }
    }
}

1 ответ

Решение

Мы нашли решение. Я наткнулся на этот набор сообщений

https://groups.google.com/forum/

Они говорят об элементе управления, называемом TabControlEx. Внизу (5-е снизу) вы увидите сообщение Саши Барбера, содержащее zip-файл с примером.

Это решило все наши проблемы, которые у нас были.

вот еще одна ссылка, где размещен код для класса

http://updatecontrols.codeplex.com/discussions/214434

Другие вопросы по тегам