Работает ли привязка данных к невидимому контролю? - PullRequest
7 голосов
/ 03 июня 2009

Это проблема .net с winforms, а не asp.net.

У меня есть форма окна с несколькими вкладками. Я устанавливаю привязки данных всех элементов управления при загрузке формы. Но я заметил, что привязки данных элементов управления на второй вкладке не работают. Эти привязки работают только тогда, когда форма загружена и когда я выбираю вторую вкладку. Это вызывает у меня подозрение: привязки данных работают только тогда, когда связанные элементы управления становятся видимыми.

Кто-нибудь может сказать мне, правда это или нет? Это несложно проверить, но я хотел бы получить подтверждение.

Спасибо

Ответы [ 6 ]

9 голосов
/ 03 июня 2009

Вы правы. Связанный с данными элемент управления не обновляется, пока элемент управления не станет видимым.

Единственная ссылка, которую я могу найти для этого на данный момент, - этот поток MSDN .

4 голосов
/ 01 июня 2011

Ваша проблема связана с поведением TabControl. См. Отчет об ошибке Microsoft . Я опубликовал обходной путь для этой проблемы, который подклассов TabControl и «Инициализирует» все страницы вкладок, когда создается элемент управления или дескриптор. Ниже приведен код обходного пути.

public partial class TabControl : System.Windows.Forms.TabControl
{
    protected override void OnHandleCreated(EventArgs e_)
    {
        base.OnHandleCreated(e_);
        foreach (System.Windows.Forms.TabPage tabPage in TabPages)
        {
            InitializeTabPage(tabPage, true, Created);
        }
    }

    protected override void OnControlAdded(ControlEventArgs e_)
    {
        base.OnControlAdded(e_);
        System.Windows.Forms.TabPage page = e_.Control as System.Windows.Forms.TabPage;
        if ((page != null) && (page.Parent == this) && (IsHandleCreated || Created))
        {
            InitializeTabPage(page, IsHandleCreated, Created);
        }
    }

    protected override void OnCreateControl()
    {
        base.OnCreateControl();
        foreach (System.Windows.Forms.TabPage tabPage in TabPages)
        {
            InitializeTabPage(tabPage, IsHandleCreated, true);
        }
    }

    //PRB: Exception thrown during Windows Forms data binding if bound control is on a tab page with uncreated handle
    //FIX: Make sure all tab pages are created when the tabcontrol is created.
    //https://connect.microsoft.com/VisualStudio/feedback/details/351177
    private void InitializeTabPage(System.Windows.Forms.TabPage page_, bool createHandle_, bool createControl_)
    {
        if (!createControl_ && !createHandle_)
        {
            return;
        }
        if (createHandle_ && !page_.IsHandleCreated)
        {
            IntPtr handle = page_.Handle;
        }
        if (!page_.Created && createControl_)
        {
            return;
        }
        bool visible = page_.Visible;
        if (!visible)
        {
            page_.Visible = true;
        }
        page_.CreateControl();
        if (!visible)
        {
            page_.Visible = false;
        }
    }
} 
1 голос
/ 11 апреля 2012

Я сам боролся с этим и пришел к выводу, что единственный обходной путь, по-видимому, помимо создания подклассов (см. Ответ hjb417), состоял в том, чтобы сделать другую вкладку видимой. Переключение на другую вкладку и возврат к предыдущей непосредственно перед отображением формы не работает. Если вы не хотите видеть вторую вкладку, я использовал следующий код в качестве обходного пути:

this.tabControl.SelectedTab = this.tabPageB; 
this.tabPageB.BindingContextChanged += (object sender, EventArgs e) => {
    this.tabContainerMain.SelectedTab = this.tabPageA; 
};

Предполагается, что tabPageA - видимая вкладка, а tabPageB - невидимая, которую вы хотите инициализировать. Это переключается на страницу B и переключается обратно после завершения привязки данных. Это невидимо для пользователя в форме.

Все еще безобразный хак, но по крайней мере это работает. Конечно, код становится еще хуже, когда у вас есть несколько вкладок.

1 голос
/ 13 сентября 2011

Мы столкнулись с подобной проблемой. Мы пытаемся записать в 2 связанных невидимых поля, чтобы мы могли изменить формат, который пишем в наш набор данных. Это прекрасно работает, когда объекты видимы, но перестает работать, когда свойство visible было изменено на false.

Чтобы обойти это, я добавил следующий код:

            // Stop our screen flickering.
        chSplitContainer.Panel2.SuspendLayout();
        // Make the bound fields visible or the binding doesn't work.
        tbxValueCr.Visible = true;
        tbxValueDb.Visible = true;

        // Update the fields here.
        <DO STUFF>

        // Restore settings to how they were, so you don't know we're here.
        tbxValueCr.Visible = false;
        tbxValueDb.Visible = false;
        chSplitContainer.Panel2.ResumeLayout();
0 голосов
/ 31 июля 2018

Основываясь на ответах, я сделал этот метод, который работает для меня:

 public partial class Form1: Form
 {
    private void Form1_Load(object sender, EventArgs e)
    {
        ...
        forceBindTabs(tabControl1);
    }

    private void forceBindTabs(TabControl ctl)
    {
        ctl.SuspendLayout();

        foreach (TabPage tab in ctl.TabPages)
            tab.Visible = true;

        ctl.ResumeLayout();
    }
 }

В дополнение к решению проблемы вкладки загружаются в начале и отображаются быстрее, когда пользователь нажимает на них.

0 голосов
/ 03 июня 2009

Это не то, с чем я сталкивался напрямую. Тем не менее может возникнуть проблема с BindingContext . Без подробностей сложно сказать, но на вашем месте я бы установил точку останова и убедился, что все элементы управления связаны в одном контексте.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...