2

在选项卡控件上,我有几个选项卡,其中一个选项卡的内容中有一个文本框。

此文本框的内容与简单的 Path=PropertyName 和 UpdateSourceTrigger=LostFocus 绑定。我使用 LostFocus 的原因是我捕获了 Textbox 的 Lost focus 事件并可能重新格式化文本。这是一个“时间”文本框,如果他们输入“0900”,我想重新格式化为“09:00”。当我按 Tab 键移动到下一个控件时,这部分效果很好,但是如果我键入“0900”然后按其他选项卡之一,我会失去焦点并重新格式化文本框中的值,但绑定永远不会被调用来更新我的对象。当我回到选项卡时,该值被空白(或重置为对象上的原始值)

任何想法为什么在更改标签页时文本框不会触发绑定更新?

注意:这也发生在与失去焦点事件相关的常规文本框上。它似乎与单击选项卡有关。

[[添加代码]]更多注释:1.我正在动态创建选项卡和选项卡上的控件(不确定是否与它有关)2.我正在使用Prism库

主窗口 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;
        }
    }
}
4

1 回答 1

2

我们找到了解决方案。我穿越了这组帖子

https://groups.google.com/forum/#!topic/wpf-disciples/HKUU61A5l74

他们谈论了一个名为 TabControlEx 的控件。在底部(倒数第 5 个),您将看到 Sacha Barber 的帖子,其中包含带有示例的 zip 文件。

它解决了我们遇到的所有问题。

这也是另一个链接,其中发布了该类的代码

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

于 2013-06-12T00:02:44.007 回答