Добрый день.
Есть две проблемы:
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 обычно )))
};
Спасибо!
Здравствуйте, Аноним, Вы писали:
А>Добрый день.
А>Есть две проблемы:
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)=>{};
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, 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