как "связать" controls
От: Volopass  
Дата: 24.02.11 17:56
Оценка:
В форме (Windows Form) есть tabControl c несколькими tabPages.
На парочке tabPages есть control (одинаковый тип — скажем comboBox) отвечающий за такой же параметр. Как сделать так чтобы при смене значения в одном менялось значение в другом.

P.s. пож-та, не предлагать вариант в SelectedIndexChanged функции одного менять значение другого.
Re: как "связать" controls
От: mrjeka Россия  
Дата: 24.02.11 18:10
Оценка:
Здравствуйте, Volopass, Вы писали:

V>В форме (Windows Form) есть tabControl c несколькими tabPages.

V>На парочке tabPages есть control (одинаковый тип — скажем comboBox) отвечающий за такой же параметр. Как сделать так чтобы при смене значения в одном менялось значение в другом.

V>P.s. пож-та, не предлагать вариант в SelectedIndexChanged функции одного менять значение другого.


Используйте BindingSource (вроде так называется в win-приложениях). Они умеют отслеживать состояние своих коллекций. И при биндинге двух контролов на один источник при изменении значения в одном будет изменено в другом.
Re[2]: как "связать" controls
От: Volopass  
Дата: 24.02.11 19:33
Оценка:
Здравствуйте, mrjeka, Вы писали:

M>Здравствуйте, Volopass, Вы писали:


V>>В форме (Windows Form) есть tabControl c несколькими tabPages.

V>>На парочке tabPages есть control (одинаковый тип — скажем comboBox) отвечающий за такой же параметр. Как сделать так чтобы при смене значения в одном менялось значение в другом.

V>>P.s. пож-та, не предлагать вариант в SelectedIndexChanged функции одного менять значение другого.


M>Используйте BindingSource (вроде так называется в win-приложениях). Они умеют отслеживать состояние своих коллекций. И при биндинге двух контролов на один источник при изменении значения в одном будет изменено в другом.


Спасибо.
Этот вариант я знаю, но то как я знаю получается уж слишком ...
Скажем у меня есть 2 textBoxes, которые реально связаны с переменной int iParameter. И хотелось бы прикрутить все это к int.
А тут надо как минимум создать DataTable, в нем Column, да еще одно Row, где и будет храниться этот int. Вот подобный пример, только над DataTable накручивается еще DataSet, а над ним еще и BindingSourсe
здесь
Re[3]: как "связать" controls
От: valker  
Дата: 26.02.11 07:43
Оценка:
Здравствуйте, Volopass, Вы писали:

V>Спасибо.

V>Этот вариант я знаю, но то как я знаю получается уж слишком ...
V>Скажем у меня есть 2 textBoxes, которые реально связаны с переменной int iParameter. И хотелось бы прикрутить все это к int.
V>А тут надо как минимум создать DataTable, в нем Column, да еще одно Row, где и будет храниться этот int. Вот подобный пример, только над DataTable накручивается еще DataSet, а над ним еще и BindingSourсe

"биндиться" можно к любому объекту с публичным свойством, который поддерживает событие ИмяСвойстваChanged, или реализует интерфейс INotifyPropertyChanged.
Re[4]: как "связать" controls
От: Volopass  
Дата: 01.03.11 00:56
Оценка:
Здравствуйте, valker, Вы писали:

V>Здравствуйте, Volopass, Вы писали:


V>>Спасибо.

V>>Этот вариант я знаю, но то как я знаю получается уж слишком ...
V>>Скажем у меня есть 2 textBoxes, которые реально связаны с переменной int iParameter. И хотелось бы прикрутить все это к int.
V>>А тут надо как минимум создать DataTable, в нем Column, да еще одно Row, где и будет храниться этот int. Вот подобный пример, только над DataTable накручивается еще DataSet, а над ним еще и BindingSourсe

V>"биндиться" можно к любому объекту с публичным свойством, который поддерживает событие ИмяСвойстваChanged, или реализует интерфейс INotifyPropertyChanged.


спасибо! я сделал это. странно, но примера для простых controls я не смог найти.
Re[5]: как "связать" controls
От: Volopass  
Дата: 21.03.11 20:40
Оценка:
Здравствуйте, Volopass, Вы писали:

V>Здравствуйте, valker, Вы писали:


V>>Здравствуйте, Volopass, Вы писали:


V>>>Спасибо.

V>>>Этот вариант я знаю, но то как я знаю получается уж слишком ...
V>>>Скажем у меня есть 2 textBoxes, которые реально связаны с переменной int iParameter. И хотелось бы прикрутить все это к int.
V>>>А тут надо как минимум создать DataTable, в нем Column, да еще одно Row, где и будет храниться этот int. Вот подобный пример, только над DataTable накручивается еще DataSet, а над ним еще и BindingSourсe

V>>"биндиться" можно к любому объекту с публичным свойством, который поддерживает событие ИмяСвойстваChanged, или реализует интерфейс INotifyPropertyChanged.


V>спасибо! я сделал это. странно, но примера для простых controls я не смог найти.


Этот вариант работает, если объект с интерфейсом INotifyPropertyChanged меняется в UI thread.
Если же он меняется в другом thread, то не работает.
Также применить control.Invoke() функцию нельзя, так как объект не знает о controls, которые прибандились.

Кто что подскажет?
Re[6]: как "связать" controls
От: baranovda Российская Империя  
Дата: 21.03.11 20:48
Оценка:
Здравствуйте, Volopass, Вы писали:

V>Также применить control.Invoke() функцию нельзя, так как объект не знает о controls, которые прибандились.

V>Кто что подскажет?

Так как условия вводной постепенно уточняются, а сама вводная всё усложняется, то скоро сюда понабегут гуру и посоветуют тебе смастерить Model-View-Presenter, который хотя и кажется поначалу страшным оверхедом, но все же в подобных задачах является и единственно верным решением, позволяющим не размазывать логику по коду кучи контролов, а сосредоточить обработку событий в одном месте.
Re[7]: как "связать" controls
От: Volopass  
Дата: 22.03.11 00:14
Оценка:
Здравствуйте, baranovda, Вы писали:

B>Здравствуйте, Volopass, Вы писали:


V>>Также применить control.Invoke() функцию нельзя, так как объект не знает о controls, которые прибандились.

V>>Кто что подскажет?

B>Так как условия вводной постепенно уточняются, а сама вводная всё усложняется, то скоро сюда понабегут гуру и посоветуют тебе смастерить Model-View-Presenter, который хотя и кажется поначалу страшным оверхедом, но все же в подобных задачах является и единственно верным решением, позволяющим не размазывать логику по коду кучи контролов, а сосредоточить обработку событий в одном месте.


В том то и дело я не размазываю логику по кучи контролс )))
Есть прибор состоящий из нескольких devices. Каждый device представляет собой объект класс и его на каждое действие выполняется соотвествующей функцией. Зачастую device медленный или оператор может что-нибудь щелкнуть на передней панели и по этому приходится еще иметь и отдельный thread в таком device. Но функции напрямую не вызываются, а применяется функции write & read, первым аргументом которой является имя параметра, по которому ищется функция. Сам параметр является классом и, кроме имени и других членов, имеет List всех контролс, которые присоеденились. Так что пока сделано так — значение параметра меняется и значения поля Text у всех контролс. Так как внутренний thread, то приходится иметь Invoke с дешифрацией.

Но хотелось бы убрать List всех контролс, да и дешифрацию c Invoke ///

Почему это пришлось сделать ... попросили сделать настраиваемую панельку параметров. Скажем для одного важны одни 5 параметров, а для другого другие. И надо было сделать так, чтобы можно было бы выбрать параметры и контролс этого параметра соотвественно менялся. Из-за этого пришлось уже сделать naming convention, подобно такой которая используется в крупных системах. Отсюда вылезли функции write-read.
Также у прибора баывает несколько методов. На каждый метод диалог и многие диалоги имеют контролс, связанный с одним параметром. Кстати в Java таких гиморов со сменой значения контролс не из UI thread нету, хотя есть другие заморочки.

Есть конечно контролс, не привязанные к прибору, но там логика простая ...
Re[7]: как "связать" controls
От: Mumitroller Беларусь  
Дата: 22.03.11 08:32
Оценка:
V>>Также применить control.Invoke() функцию нельзя, так как объект не знает о controls, которые прибандились.
V>>Кто что подскажет?

B>Так как условия вводной постепенно уточняются, а сама вводная всё усложняется, то скоро сюда понабегут гуру и посоветуют тебе смастерить Model-View-Presenter, который хотя и кажется поначалу страшным оверхедом, но все же в подобных задачах является и единственно верным решением, позволяющим не размазывать логику по коду кучи контролов, а сосредоточить обработку событий в одном месте.


А в этом Model-View-Presenter переправлять оповещения об изменениях в UI-поток с помощью http://msdn.microsoft.com/en-us/library/system.componentmodel.asyncoperationmanager.aspx

Mumitroller
... << RSDN@Home 1.2.0 alpha 4 rev. 0>>
Re[8]: как "связать" controls
От: Mumitroller Беларусь  
Дата: 22.03.11 08:46
Оценка:
Здравствуйте, Mumitroller, Вы писали:

V>>>Также применить control.Invoke() функцию нельзя, так как объект не знает о controls, которые прибандились.

V>>>Кто что подскажет?

B>>Так как условия вводной постепенно уточняются, а сама вводная всё усложняется, то скоро сюда понабегут гуру и посоветуют тебе смастерить Model-View-Presenter, который хотя и кажется поначалу страшным оверхедом, но все же в подобных задачах является и единственно верным решением, позволяющим не размазывать логику по коду кучи контролов, а сосредоточить обработку событий в одном месте.


M>А в этом Model-View-Presenter переправлять оповещения об изменениях в UI-поток с помощью http://msdn.microsoft.com/en-us/library/system.componentmodel.asyncoperationmanager.aspx


Точнее — переправить с помощью http://msdn.microsoft.com/en-us/library/system.componentmodel.asyncoperation.post.aspx, а саму AsyncOperation получить с помощью вызова AsyncOperationManager.CreateOperation в UI-потоке.

Mumitroller
... << RSDN@Home 1.2.0 alpha 4 rev. 0>>
Re[9]: как "связать" controls
От: Volopass  
Дата: 23.03.11 00:52
Оценка:
Здравствуйте, Mumitroller, Вы писали:

M>Здравствуйте, Mumitroller, Вы писали:


V>>>>Также применить control.Invoke() функцию нельзя, так как объект не знает о controls, которые прибандились.

V>>>>Кто что подскажет?

B>>>Так как условия вводной постепенно уточняются, а сама вводная всё усложняется, то скоро сюда понабегут гуру и посоветуют тебе смастерить Model-View-Presenter, который хотя и кажется поначалу страшным оверхедом, но все же в подобных задачах является и единственно верным решением, позволяющим не размазывать логику по коду кучи контролов, а сосредоточить обработку событий в одном месте.


M>>А в этом Model-View-Presenter переправлять оповещения об изменениях в UI-поток с помощью http://msdn.microsoft.com/en-us/library/system.componentmodel.asyncoperationmanager.aspx


M>Точнее — переправить с помощью http://msdn.microsoft.com/en-us/library/system.componentmodel.asyncoperation.post.aspx, а саму AsyncOperation получить с помощью вызова AsyncOperationManager.CreateOperation в UI-потоке.


M>Mumitroller


Мне кажется это не совсем то, что я хочу. Честно говоря, я не совсем разобрался в обрывках кода по ссылкам, но нашел пример здесь . Получается, что вывод привязан к конкретному control.
У меня же control binds к объекту NotifyPropertyChangedString класса

    //usage
    NotifyPropertyChangedString oNotifiableComboboxString = new NotifyPropertyChangedString();
    NotifyPropertyChangedString oNotifiableButtonString = new NotifyPropertyChangedString();
    NotifyPropertyChangedString oNotifiableRbTextboxString = new NotifyPropertyChangedString();

    public Form1()
    {
        ....
        comboBox2.DataBindings.Add(new Binding("Text", oNotifiableComboboxString, "StrValue"));
        button2.DataBindings.Add(new Binding("Text", oNotifiableButtonString, "StrValue"));
        textBox3.DataBindings.Add(new Binding("Text", oNotifiableRbTextboxString, "StrValue"));
        ...
    }

    public class NotifyPropertyChangedString : NotifyPropertyChangedBase
    {
        private string _StrValue;
        public string StrValue
        {
            get { return _StrValue; }
            set
            {
                NotifyPropertyChanged("StrValue", ref _StrValue, ref value);
            }
        }
    }

    public abstract class NotifyPropertyChangedBase : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        protected bool NotifyPropertyChanged<T>(string propertyName, ref T oldValue, ref T newValue)
        {
            if (oldValue == null && newValue == null)
            {
                return false;
            }
            if ((oldValue == null && newValue != null) || !oldValue.Equals((T)newValue))
            {
                oldValue = newValue;
                if (this.PropertyChanged != null)
                {
                    this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
                }
                return true;
            }
            return false;
        }
        private delegate void vDFUpdateParameter( string StrValue1);
        private void vFUpdateParameter(string StrValue1)
        {
            if (this.PropertyChanged != null)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs(StrValue1));
            }
        }
    }


ключевой момент в том что любой thread должен менять oNotifiableComboboxString.StrValue и тогда все привязанные controls тоже поменяются.
Как тут сделать?
Re[10]: как "связать" controls
От: Mumitroller Беларусь  
Дата: 23.03.11 09:23
Оценка:
Здравствуйте, Volopass, Вы писали:

V>ключевой момент в том что любой thread должен менять oNotifiableComboboxString.StrValue и тогда все привязанные controls тоже поменяются.

V>Как тут сделать?

Так, как говорилось выше — использовать экземпляр AsyncOperation для выполнения действия в нужном (UI) потоке. Применительно к вашему случаю схема может быть следующей:


Но тут есть один подводный камень, о котором следует помнить — может оказаться, что потоки генерируют обновления быстрее, чем UI-поток может их обработать. В результате память начинает забиваться объектами, передаваемыми в UI-поток и очень легко может закончиться. Если такое у вас возможно, то следует подумать об оптимизации количества обновлений и поведении системы, если такая ситуация все-таки случилась. Например, при достижении некоторого порога скорости поступления обновлений можно либо отбрасывать излишние обновления, либо притормаживать потоки, которые их генерируют.

Mumitroller
... << RSDN@Home 1.2.0 alpha 4 rev. 0>>
Re[11]: как "связать" controls
От: Volopass  
Дата: 23.03.11 16:39
Оценка:
Здравствуйте, Mumitroller, Вы писали:

M>Здравствуйте, Volopass, Вы писали:


V>>ключевой момент в том что любой thread должен менять oNotifiableComboboxString.StrValue и тогда все привязанные controls тоже поменяются.

V>>Как тут сделать?

M>Так, как говорилось выше — использовать экземпляр AsyncOperation для выполнения действия в нужном (UI) потоке. Применительно к вашему случаю схема может быть следующей:


M>

M>Но тут есть один подводный камень, о котором следует помнить — может оказаться, что потоки генерируют обновления быстрее, чем UI-поток может их обработать. В результате память начинает забиваться объектами, передаваемыми в UI-поток и очень легко может закончиться. Если такое у вас возможно, то следует подумать об оптимизации количества обновлений и поведении системы, если такая ситуация все-таки случилась. Например, при достижении некоторого порога скорости поступления обновлений можно либо отбрасывать излишние обновления, либо притормаживать потоки, которые их генерируют.


M>Mumitroller


Спасибо. Этот вариант понятен.
Но тут 2 проблемы.
1. Хочется, чтобы DoSetComboboxString() была одна на все про все. Поэтому UI ничего не знает о конкретном oNotifiableComboboxString. Это наверное можно обойти использовав

struct SNotifiableData{
    NotifyPropertyChangedString oNotifyPropertyChangedString;
    string StrValue;
}
...
private void DoSetComboboxString(object data)
{
    // этот код выполняется в UI-потоке, поэтому нотификация работает
    SNotifiableData oSNotifiableData = (SNotifiableData) object;
    oSNotifiableData.oNotifyPropertyChangedString.StrValue = oSNotifiableData.StrValue;
}

2. Thread, а точнее класс, в котором он определен, ничего не знает о Form. Поэтому как вызвать вот такое form.SetComboboxString(***) непонятно
Можно конечно притащить form в класс, но очень бы не хотелось ...
Re[12]: как "связать" controls
От: Mumitroller Беларусь  
Дата: 24.03.11 09:00
Оценка:
Здравствуйте, Volopass, Вы писали:

V>Спасибо. Этот вариант понятен.

V>Но тут 2 проблемы.

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

V>1. Хочется, чтобы DoSetComboboxString() была одна на все про все. Поэтому UI ничего не знает о конкретном oNotifiableComboboxString. Это наверное можно обойти использовав


V>
V>struct SNotifiableData{
V>    NotifyPropertyChangedString oNotifyPropertyChangedString;
V>    string StrValue;
V>}
V>...
V>private void DoSetComboboxString(object data)
V>{
V>    // этот код выполняется в UI-потоке, поэтому нотификация работает
V>    SNotifiableData oSNotifiableData = (SNotifiableData) object;
V>    oSNotifiableData.oNotifyPropertyChangedString.StrValue = oSNotifiableData.StrValue;
V>}
V>


Вполне себе вариант. Можно еще попробовать использовать лямбду вместо DoSetComboboxString — возможно, это будет читабельнее.

V>2. Thread, а точнее класс, в котором он определен, ничего не знает о Form. Поэтому как вызвать вот такое form.SetComboboxString(***) непонятно

V>Можно конечно притащить form в класс, но очень бы не хотелось ...

Так или иначе какой-то канал для передачи данных между классом и формой организовывать придется. И каким он будет — это вопрос архитектуры, а давать советы по архитектуре я не возьмусь.

Mumitroller
... << RSDN@Home 1.2.0 alpha 4 rev. 0>>
Re[13]: как "связать" controls
От: Аноним  
Дата: 25.03.11 06:22
Оценка:
Здравствуйте, Mumitroller, Вы писали:

M>Здравствуйте, Volopass, Вы писали:


V>>Спасибо. Этот вариант понятен.

V>>Но тут 2 проблемы.

M>Своим примером я лишь продемонстрировал способ, которым можно воспользоваться, когда надо выполнить некоторое действие в заранее известном потоке. Поэтому в примере нет ничего не относящегося к вопросу.


V>>1. Хочется, чтобы DoSetComboboxString() была одна на все про все. Поэтому UI ничего не знает о конкретном oNotifiableComboboxString. Это наверное можно обойти использовав


V>>
V>>struct SNotifiableData{
V>>    NotifyPropertyChangedString oNotifyPropertyChangedString;
V>>    string StrValue;
V>>}
V>>...
V>>private void DoSetComboboxString(object data)
V>>{
V>>    // этот код выполняется в UI-потоке, поэтому нотификация работает
V>>    SNotifiableData oSNotifiableData = (SNotifiableData) object;
V>>    oSNotifiableData.oNotifyPropertyChangedString.StrValue = oSNotifiableData.StrValue;
V>>}
V>>


M>Вполне себе вариант. Можно еще попробовать использовать лямбду вместо DoSetComboboxString — возможно, это будет читабельнее.


V>>2. Thread, а точнее класс, в котором он определен, ничего не знает о Form. Поэтому как вызвать вот такое form.SetComboboxString(***) непонятно

V>>Можно конечно притащить form в класс, но очень бы не хотелось ...

M>Так или иначе какой-то канал для передачи данных между классом и формой организовывать придется. И каким он будет — это вопрос архитектуры, а давать советы по архитектуре я не возьмусь.


M>Mumitroller


вообщем пришлось мне почитать ... вот тут здесь описано как легко сделать через SynchronizationContext.
есть еще пара вариантов это сделать один из которых асинхронный.
Re[14]: как "связать" controls
От: Mumitroller Беларусь  
Дата: 25.03.11 07:11
Оценка:
Здравствуйте, <Anonymous>, Вы писали:

A>вообщем пришлось мне почитать ... вот тут здесь описано как легко сделать через SynchronizationContext.

A>есть еще пара вариантов это сделать один из которых асинхронный.

Вроде читал где-то, что AsyncOperation — это обертка над SynchronizationContext. Но я не заглядывал внутрь, может быть это мне только показалось.

Mumitroller
... << RSDN@Home 1.2.0 alpha 4 rev. 0>>
Re[15]: как "связать" controls
От: Volopass  
Дата: 25.03.11 17:47
Оценка:
Здравствуйте, Mumitroller, Вы писали:

M>Здравствуйте, <Anonymous>, Вы писали:


A>>вообщем пришлось мне почитать ... вот тут здесь описано как легко сделать через SynchronizationContext.

A>>есть еще пара вариантов это сделать один из которых асинхронный.

M>Вроде читал где-то, что AsyncOperation — это обертка над SynchronizationContext. Но я не заглядывал внутрь, может быть это мне только показалось.


M>Mumitroller


наоборот. SynchronizationContext должна быть обертка над AsyncOperation
Re[16]: как "связать" controls
От: Mumitroller Беларусь  
Дата: 26.03.11 10:46
Оценка:
Здравствуйте, Volopass, Вы писали:

V>наоборот. SynchronizationContext должна быть обертка над AsyncOperation


Reflector с вами не согласен:
[HostProtection(SecurityAction.LinkDemand, SharedState=true)]
public sealed class AsyncOperation
{
    // Fields
    private bool alreadyCompleted;
    private SynchronizationContext syncContext; // <====
    private object userSuppliedState;

    // Methods
    private AsyncOperation(object userSuppliedState, SynchronizationContext syncContext);
    internal static AsyncOperation CreateOperation(object userSuppliedState, SynchronizationContext syncContext);
    protected override void Finalize();
    public void OperationCompleted();
    private void OperationCompletedCore();
    public void Post(SendOrPostCallback d, object arg);
    public void PostOperationCompleted(SendOrPostCallback d, object arg);
    private void VerifyDelegateNotNull(SendOrPostCallback d);
    private void VerifyNotCompleted();

    // Properties
    public SynchronizationContext SynchronizationContext { [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] get; }
    public object UserSuppliedState { [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] get; }
}


Mumitroller
... << RSDN@Home 1.2.0 alpha 4 rev. 0>>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.