[WPF] Вопрос про биндинг элемента List в TextBox и delegate
От: Аноним  
Дата: 24.02.11 00:31
Оценка:
Добрый день.
Есть две проблемы:
1. Как правильно "прибиндить" такое дело:
Есть объект, у которого имеется свойство "ABC" типа List<MyType>. Реализованы оператор [string] и [int], которые возвращают значение свойтсва "Value" элемента типа MyType.
Нужно прибиндить элемент этого списка например к TextBox:

  <TextBox>
     <TextBox.Text>
          <Binding Path="Object1.ABC['Элемент 1'].Value" ElementName="Window" 
                Mode="TwoWay" FallbackValue="Fall" TargetNullValue="NUll">
          </Binding>
     </TextBox.Text>
  </TextBox>


Постоянно в поле попадает Fall. Как правильно тут сделать?

2. Есля к события подписываюсь так:

window.MyEvent += delegate { ........... 

Как тут добраться до EventArgs, которое e обычно )))
                                              
};


Спасибо!
Re: [WPF] Вопрос про биндинг элемента List в TextBox и deleg
От: Dron247  
Дата: 24.02.11 03:01
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Добрый день.

А>Есть две проблемы:

1) Поможет свой конвертер(IValueConverter), тут нужно подробнее узнать об архитектуре, если mvvm то решение одно, если нет — то другое
2) а почему просто не использовать Event вместо delegate? можно было-бы использовать например так

window.OnLoad += (s,e) =>{
    DoSomething(e);
};

в любом случае e должно объявляться в делегате, а при вызове метода, на который ссылается делегат е туда передается самим контролом
вот пример создания события:


//Контрол
public class MyPanel : UIElement
{
...
    public event EventHandler Loaded;
    private void OnLoaded()
    {
        if (Loaded!=null) Loaded(this, EventArgs.Empty);
    }
...
    private void Init()
    {
    ...
        OnLoaded();
    }
...
}



//Приемник
public partial class myForm : Form
{
    public myForm()
    {
        myControl.Loaded+=(s,e)=>{DoSomethingWithSender(s)};
    }
...
}

Как-то так, если я правильно понял.
Если свой контрол вы не делали и подписываетесь на готовое событие, то будет достаточно +=(s,e)=>{};


Твой IP на моем юзербаре
Re[2]: [WPF] Вопрос про биндинг элемента List в TextBox и de
От: Аноним  
Дата: 24.02.11 07:45
Оценка:
Здравствуйте, Dron247, Вы писали:

D>1) Поможет свой конвертер(IValueConverter), тут нужно подробнее узнать об архитектуре, если mvvm то решение одно, если нет — то другое


Сапсибо!
Пока не mvvm...
А как через конверторы, т.е. вывести значение я смогу, а опри изменении его в поле в методе ConvertBack как определеить, в какой элемент его запихивать Object1.ABC['Элемент 1'].Value = value
Re[3]: [WPF] Вопрос про биндинг элемента List в TextBox и de
От: Dron247  
Дата: 24.02.11 08:38
Оценка:
Здравствуйте, Аноним, Вы писали:

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


D>>1) Поможет свой конвертер(IValueConverter), тут нужно подробнее узнать об архитектуре, если mvvm то решение одно, если нет — то другое


А>Сапсибо!

А>Пока не mvvm...
А>А как через конверторы, т.е. вывести значение я смогу, а опри изменении его в поле в методе ConvertBack как определеить, в какой элемент его запихивать Object1.ABC['Элемент 1'].Value = value

Ваш Object1.ABC['Элемент 1'].Value должен быть открыт для записи. Конвертер ничего не знает о привязке, он получает конкретное значение из привязки и преобразует его в нужный тип. Тоесть ему на вход нужно подать корректную привязку, на выходе получите требуемый объект,
вот пример:

        class FlagConverter : IValueConverter
        {
            public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {
                string v = value.ToString();
                return "./../Data/Images/Flags/{0}.png".FormatFor(v.ToLower());
            }

            public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {
                throw new NotImplementedException();
            }
        }

этот конвертер получает на вход код страны, и дописывает к нему путь, по которому потом будет извлечена картинка в UI.
FormatFor — экстеншн метод для строк, просто более удобное представление string.Format().
Этот класс вложенный в мой биндинг, вот код

    class FlagBinding : MarkupExtension
    {
        class FlagConverter : IValueConverter
        {
            public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {
                string v = value.ToString();
                return "./../Data/Images/Flags/{0}.png".FormatFor(v.ToLower());
            }

            public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {
                throw new NotImplementedException();
            }
        }

        public FlagBinding(Binding binding)
        {
            this.binding = binding;
        }

        public Binding binding { get; set; }

        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            binding.Converter = new FlagConverter();
            return binding.ProvideValue(serviceProvider);
        }
    }


Использование:

              <Image 
                    VerticalAlignment="Center" 
                    Margin="5,0,0,0"                      
                    Source="{markup:FlagBinding {Binding CountryCode}}"                 
                    Stretch="None"/>



Короче суть конвертера в том, что он получает объект на вход, анбоксит, преобразует и возвращает. Далее инфраструктура впф через рефлекшн еще раз анбоксит и отображает.
При ConvertBack берется значение, боксится, передается в конвертер, там преобразуется, и передается обратно биндингу, который приводит к вашему полю, автоматом анбоксит и вы получаете значение

Я пока еще не силен в WPF, и потому хз как там мега-хитрые выражения в привязках строить. Обычно это можно разрулить архитектурно и привязывать уже упрощенные объекты, скажем путем введения свойства CurrentItem в модели или в codebehind


Твой IP на моем юзербаре
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.