First open-source experience.

Finally I pushed sources of an almost 9-month old solution to my github. That’s WPF application to work with Upwork API. For now it does fast nothing except of receiving job offers. There is possibility to keep several pages with different filters, rows with jobs could be expanded for more details and have buttons with url to appropriate job web page.
API has much more possibilities, which I hopefully will add sometime, the only thing here is lack of documentation about answers from server (I’m about fields and their types).
Main reason to put solution onto github is .NetStandard1.1 library which interact with API and is written in C# – I didn’t find any implementations of similar libraries for .Net, so I hope it’ll be helpful for someone.
I tried to make application more comfortable (at least because I use it by myself), so application minimizes to tray instead of closing (actually that’s little unexpected) – to close the app choose “Close” from context menu of tray icon. There is EF7 + SQL CE used to store pages and filters, and are implemented popups for newly found jobs (on double-click on popup text you will open appropriate tab in application), popups could be disabled, otherwise it’s possible to set how long in seconds popup will be showed.
Unfortunately I can’t share my API keys, so I can’t put binary compiled version right away, because keys are easily extracted in this case. There is a way to receive API key by yourself and use it. Otherwise wait some time while I’m adding new separate library for requesting API under some license, which deny reverse engineering, because I don’t want to be responsible for key loss. If you know some other way to more securely share binaries, then let me know.
I’m open to any offers about ways to improve current implementation, so don’t hesitate to share your minds.

Advertisements

WPF Binding dynamic converter.

Some time ago I was stuck with problem of using dynamically created converters. So as it turned out the problem could be solved pretty easy – by using MarkupExtension. Create some container like Dictionary and fill it with dynamically created converters, after that create a class like following:

    public class GetConverterExtension : MarkupExtension
    {
        private string _converterName = string.Empty;

        public GetConverterExtension(String converterName)
        {
            if (String.IsNullOrWhiteSpace(converterName))
            {
                throw new ArgumentNullException(nameof(converterName));
            }

            _converterName = converterName;
        }
        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            return BindingHelper.Instance.Converters[_converterName];
        }
    }

BindingHelper.Instance.Converters is dictionary I talked above.

And that’s all, simply implement appropriate namespace within XAML and use your converters.

Code-behind:

BindingHelper.Instance.Converters.Add("NowDifferenceHours",
                new GenericConverter<DateTime, double>(dt => DateTime.Now.Subtract(dt).TotalHours));

XAML:

    <StackPanel Orientation="Horizontal">
        <TextBlock Text="{Binding DateCreated, StringFormat='{}{0:dd-MM-yyyy HH:mm:ss}'}" />
        <TextBlock Margin="6,0,0,0"
                    Text="{Binding DateCreated, Converter={converters:GetConverter 'NowDifferenceHours'}, StringFormat={}{0:[-00.00]}}" />
    </StackPanel>

time_diff

 

Here first textbox shows DateTime from model and second textbox shows difference in hours with current time.

Incorrect relative binding behavior inside of TabControl

Hey, people! I’m finally back into development of my app.

And right after start I collided with one unpleasant situation. For me it seems like a bug, but maybe it isn’t (let me know in comments if so). What happened?
I have array of filters, each filter holds array of categories and each category holds array of subcategories. For display purposes I have TabControl – one tab for one filter – and on each tab I have 2 ListViews(first for categories, second for subcategories). Second ListView takes its source from Subcategories property of SelectedItem of first ListView. On the whole it looks next way:

<StackPanel Orientation="Horizontal">
    <ListBox ItemsSource="{Binding ElementName=cntrl, Path=Categories, Mode=OneWay}"
             SelectedValue="{Binding Filter.Category, Mode=TwoWay}" SelectedValuePath="Title" />

    <ListBox ItemsSource="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type StackPanel}}, Path=Children[0].SelectedItem.SubCategories, Mode=OneWay}"
             SelectedValue="{Binding Filter.Subcategory, Mode=TwoWay}" SelectedValuePath="Title" />
</StackPanel>

You can note ItemsSource’s binding with RelativeSource in the second ListView. All seems good and second ListView successfully takes subcategories for category from first ListView.
But! If I select some category and subcategory, switch to next tab and switch back, then my subcategory is missed. So I started debugger and found next thing, which happens at the moment of tab switch:
debug
For some reason null is given to Subcategory, but I didn’t change parent Category and breakpoint at Category’s setter didn’t fire too. Herewith if on both tabs is selected the same category, then subcategory doesn’t set to null. So why this happens?
I put subcategories ListView before categories ListView like this:

<StackPanel Orientation="Horizontal">
    <ListBox ItemsSource="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type StackPanel}}, Path=Children[1].SelectedItem.SubCategories, Mode=OneWay}"
             SelectedValue="{Binding Filter.Subcategory, Mode=TwoWay}" SelectedValuePath="Title" />
    
    <ListBox ItemsSource="{Binding ElementName=cntrl, Path=Categories, Mode=OneWay}"
             SelectedValue="{Binding Filter.Category, Mode=TwoWay}" SelectedValuePath="Title" />
</StackPanel>

Now if I switch tabs, then null doesn’t put to subcategory value and Filter.Subcategory holds its value between switches. But after switchback appropriate radiobutton isn’t selected.
debug2
Herewith subcategory items are displayed correctly. So what happens here?

When engine draws tab after switch it goes from begin of tab’s XAML to the end. But for some reason it doesn’t clear the tab, it redraws controls one by one. So we receive above results. I believe happens something similar to following:

1) when subcategories list is second: engine redraws categories list, but subcategories list is still old (from old tab). Since second list(subcategory) has relative binding to the first list(category), it becomes new ItemsSource(because categories list is already redrawn and has different SelectedItem). So subcategories list is changed, but there isn’t found old subcategory value, so it’s set to null value. After all engine redraws second list, but subcategory value is already missed.

2) when subcategories list goes first: engine redraws subcategories list, but relative binding doesn’t fire yet, because second list isn’t redrawn. However binding to Filter.Subcategory on SelectedValue attribute fires and set selected list item to nothing (because for now list is empty). After that engine redraws second list, relative binding on first list is fired, but binding on SelectedValue has fired already, so we have correct Filter.Subcategory value, but also list with no selected subcategory. (Note: it’s incorrect behavior, because if we set same values before form load, then all works as expected, see the screenshot below)
debug3

So I believe problem is located. But we still don’t know what to do. So as I believe in above behavior of engine, I thought that some delay before setting bindings could be helpful, because this delay let engine redraw the tab to the end. Luckily binding has exact such property – Delay. So I add delay to binding to Filer.Subcategory like this:

<StackPanel Orientation="Horizontal">
    <ListBox ItemsSource="{Binding ElementName=cntrl, Path=Categories, Mode=OneWay}"
             SelectedValue="{Binding Filter.Category, Mode=TwoWay}" SelectedValuePath="Title" />

    <ListBox ItemsSource="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type StackPanel}}, Path=Children[0].SelectedItem.SubCategories, Mode=OneWay}"
             SelectedValue="{Binding Filter.Subcategory, Delay=1, Mode=TwoWay}" SelectedValuePath="Title" />
</StackPanel>

And that works. I think couple of ticks is enough for engine to draw the tab to the end, and delay for even 1 millisecond doesn’t let change Filter.Subcategory to null. Actually this delay for millisecond looks like dirty hack, but as it fixes above problem, it make me think that my thoughts about redrawing tab controls one-by-one are correct.
If you can refer me to right direction related to this problem then let me know in comments what happens here.
Hope that helps :)

WPF dynamic bindings&convertes

Hi, people! I’m really tired of continuous creating of Converters in each new WPF project. I don’t like how they must be applied in XAML and I don’t like all these similar classes. So this time I decided – enough.

First of all I created generic converter(the only converter which I wanted to see in my project). That’s the code:

public class GenericConverter<TIn, TOut> : IValueConverter
{
    private Func<TIn, TOut> _convert = null;
    private Func<TOut, TIn> _convertBack = null;

    public GenericConverter(Func<TIn, TOut> convert = null, Func<TOut, TIn> convertBack = null)
    {
        _convert = convert;
        _convertBack = convertBack;
    }

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (_convert == null)
        {
            throw new NotImplementedException();
        }

        return _convert((TIn)value);
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (_convertBack == null)
        {
            throw new NotImplementedException();
        }

        return _convertBack((TOut)value);
    }
}

My next thought was to collect different generics implementations in some dictionary and call them from XAML. But it’s impossible as you can’t use binding on bindings converter parameter (or I just didn’t find any solution). Of course I could create many static resources from my code-behind dictionary, but I don’t want to go this way.

So next I decided to make dictionary with bindings, which I created somewhere in code like this one:

var binding = new Binding("IsConnected")
{
    Source = DataModel,
    Mode = BindingMode.OneWay,
    Converter = new GenericConverter<bool, Visibility>((bool b) =>
        {
            return (Visibility)(b ? Visibility.Visible : Visibility.Collapsed);
        })
};

As you can see converter here is really small. Even if you want to use it few times, you always can store it in some collection of similar converters and don’t give a f#ck about all these converter classes.
So I created dictionary with bindings like one above, but again – I couldn’t bind any property to them. And at all it looks silly – binding to binding.

And here we come to my final realization. In previous post you could see BindingHelper. It’s in play again – now it looks like this:

public class BindingHelper : BindableBase
{
    #region Singleton implementation
    private static BindingHelper _instance = null;
    private BindingHelper()
    {
        DynamicBindings = new DPResolver(() => OnPropertyChanged(nameof(DynamicBindings)));
    }

    public static BindingHelper Instance
    {
        get
        {
            if (_instance == null)
            {
                _instance = new BindingHelper();
            }
            return _instance;
        }
    }
    #endregion Singleton implementation

    #region Enums
    /* cutted for sake, see prev.post for it */
    #endregion Enums

    #region DP resolver
    public DPResolver DynamicBindings { get; private set; }
    public class DPResolver : DependencyObject
    {
        private Action _resolverChanged;
        private Dictionary<String, DependencyProperty> _innerCache = new Dictionary<string, DependencyProperty>();

        public DPResolver(Action resolverChanged)
        {
            _resolverChanged = resolverChanged;
        }
        public Object this[String dpName]
        {
            get
            {
                if (_innerCache.ContainsKey(dpName))
                {
                    return GetValue(_innerCache[dpName]);
                }
                return null;
            }
            set
            {
                if (_innerCache.ContainsKey(dpName) && value != this[dpName])
                {
                    SetValue(_innerCache[dpName], value);
                    _resolverChanged();
                }
            }
        }

        public void RegisterBinding(String dpName, Type endType, Binding binding)
        {
            if (String.IsNullOrWhiteSpace(dpName))
            {
                throw new ArgumentNullException(nameof(dpName));
            }
            if (binding == null)
            {
                throw new ArgumentNullException(nameof(binding));
            }

            DependencyProperty dp;
            if (_innerCache.ContainsKey(dpName))
            {
                dp = _innerCache[dpName];
            }
            else
            {
                dp = DependencyProperty.Register(dpName, endType, typeof(DPResolver), new PropertyMetadata((d,e) => _resolverChanged()));
                _innerCache.Add(dpName, dp);
            }

            if (dp != null)
            {
                var be = BindingOperations.SetBinding(this, dp, binding);
                _resolverChanged();
            }
        }
    }
    #endregion DP resolver
}

What happens here? First of all see at DPResolver class. It inherits from DependencyObject, that’s needed for bindings. Class has indexer, which call GetValue/SetValue for appropriate DependencyProperty in innerDictionary, DP is taken by string name. Actually it seems similar to default DP snippet in visual studio (type ‘propdp’ and press Tab), except that depends on property name we return different values:dp snippet

RegisterBinding method register new DependencyProperty if it still doesn’t exists for dpName, and next it set our binding for this DP.

Idea is next: as we can’t store bindings, we would store DependencyProperty collection. We always can append Binding to one of DPs in collection. We create binding (with our generic converter inside), next we bind it to some DP inside BindingHelper. All we need next is to bind property in XAML to same DP inside BindingHelper.

Do you remember sample binding in begin of this post? Now we can register it in BindingHelper next way:

BindingHelper.Instance.DynamicBindings.RegisterBinding("mainGridVisibility", typeof(Visibility), binding);

Last thing we will made is binding in XAML:

<Grid xmlns:lc="clr-namespace:BindingHelpers_Namespace">
    <Grid.Resources>
        <ResourceDictionary>
            <ObjectDataProvider x:Key="bindingHelper" ObjectInstance="{x:Static lc:BindingHelper.Instance}" />
        </ResourceDictionary>
    </Grid.Resources>

    <TabControl Visibility="{Binding Source={StaticResource bindingHelper}, Path=DynamicBindings[mainGridVisibility], Mode=OneWay}" />
</Grid>

That’s all, now we can drop out all static converters. I know solution is very suspicious, but it totally suits my needs on my little project.
Give attention to this one string inside RegisterBinding method:

dp = DependencyProperty.Register(dpName, endType, typeof(DPResolver), new PropertyMetadata((d,e) => _resolverChanged()));

As you can see we call _resolverChanged() each time as any of our inner DPs was changed (_resolverChanged() fire PropertyChanged for DynamicBindings property inside BindingHelper), which will cause refresh in all elements, which we have binded to BindingHelper’s DynamicBindings property. That’s definitelly is a disadvantage, but I think you can avoid this by realizing DPResolver class similary to ObservableCollection.

I hope this solution might help someone with non-trivial needings on project.

XAML binding to Enum

Hello girls and boys! Today I faced with already solved in many ways Task – binding enum values to combobox. There are many articles on the web about it, this one is most beautiful I found with 10 minutes research. But all these techniques seems to me unintuitive a little, that’s just my vision, but I decided to take another way to solve my problem.

Here I will give simplest possible implementation, which ofc can be complicated with more features. First of all we’ll create our helper class for bindings(I made it in singletone pattern, but it’s optional). BindableBase here is a custom base class, which implements INotifyPropertyChanged interface:

    public class BindingHelper : BindableBase
    {
        private static BindingHelper _instance = null;
        private BindingHelper() { /* Here you can put some default registers */ }
        public static BindingHelper Instance
        {
            get
            {
                if (_instance == null)
                {
                    _instance = new BindingHelper();
                }
                return _instance;
            }
        }

        public Dictionary<String, Object> Enums { get; } = new Dictionary<string, object>();

        public bool RegisterEnum(Type enumType)
        {
            if (!enumType.IsEnum || Enums.ContainsKey(enumType.Name))
            {
                return false;
            }

            Enums.Add(enumType.Name, Enum.GetNames(enumType));
            OnPropertyChanged(nameof(Enums));
            return true;
        }
    }

Next somewhere in the code-behind we must register enum type with BindingHelper. In my case it could be BindingHelper constructor, but I prefer do it somewhere in code:

    BindingHelper.Instance.RegisterEnum(typeof(YourEnumType));

And last step is to bind our ComboBox:

    <ComboBox xmlns:local="clr-namespace:Namespace_Of_BindingHelper"
                ItemsSource="{Binding Source={x:Static local:BindingHelper.Instance}, Path=Enums[YourEnumType]}" />

Ofc xmlns you can implement within any parent element of combobox. And that’s all. Why I like this approach more than others? I think because here we become single entry point through BindingHelper, it’s more intuitive and easily to understand what is going on, and we can simply implement any processing logic of binded entities. Eg. you want some keys to be delivered with enum values, then you could just modify RegisterEnum method like this:

    public bool RegisterEnum(Type enumType)
    {
        if (!enumType.IsEnum || Enums.ContainsKey(enumType.Name))
        {
            return false;
        }

        List<Tuple<Enum, String>> tuples = new List<Tuple<Enum, string>>();
        foreach (Enum e in Enum.GetValues(enumType))
        {
            tuples.Add(new Tuple<Enum, string>(e, e.ToString()));
        }
        Enums.Add(enumType.Name, tuples);
        OnPropertyChanged(nameof(Enums));
        return true;
    }

And XAML:

    <ComboBox xmlns:local="clr-namespace:Namespace_Of_BindingHelper"
                SelectedValuePath="Item1" DisplayMemberPath="Item2"
                ItemsSource="{Binding Source={x:Static local:BindingHelper.Instance}, Path=Enums[YourEnumType]}"
                SelectedValue="{Binding YourEnumType_Variable, Mode=TwoWay}" />

Ofc such approach can be handled not only to enums, but to any other data. I hope this will help someone in the future.

Json.NET different property names resolving

Hi, boys and girls. Short post about how I resolved little local issue. Maybe someday someone might find this useful.

I’m developing library for 3rd party API for now. Format in which I’m receiving data is json. Trouble was with API answer’s formatting. API returns something like this:

{
    "server_time": "1459218903",
    "auth_user": {...},
    "some_entity_name": {some_entity_data}
}

where some_entity_name could be different for different API methods(“user”, “team” etc). But I wanted to map this field into single property within my generic:

    public class Answer<TEntity> where TEntity : class, IEntity
    {
        [JsonProperty("server_time")]
        public long ServerTime { get; set; }

        [JsonProperty("auth_user")]
        public Object AuthUser { get; set; }

        [JsonProperty("error")]
        public Error Error { get; set; }

        public TEntity Entity { get; set; } // <-- here
    }

Ofc JsonProperty attribute is useless for this case. So after some research I found pretty solution for that situation. I implemented custom ContractResolver and one attribute. So my class implementation for generic parameter becomes:

    [Attributes.JsonPropertyMap("user")]
    public class User : IEntity
    {

Attribute code(nothing special):

    [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
    public class JsonPropertyMapAttribute : Attribute
    {
        public JsonPropertyMapAttribute(String mapToName)
        {
            MapToName = mapToName;
        }

        public String MapToName { get; set; }
    }

And that’s resolver code:

using ApiLibrary.ApiEntities.Attributes;
using Newtonsoft.Json.Serialization;
using System;
using System.Reflection;

namespace ApiLibrary.ApiEntities.Base
{
    public class EntityContractResolver<TEntity>: DefaultContractResolver where TEntity : class
    {
        protected override string ResolvePropertyName(string propertyName)
        {
            if (propertyName == nameof(Answer.Entity))
            {
                Type entityType = typeof(TEntity);
                var jsonMapAttribute = entityType.GetTypeInfo().GetCustomAttribute<JsonPropertyMapAttribute>();
                if (!String.IsNullOrWhiteSpace(jsonMapAttribute?.MapToName))
                {
                    return jsonMapAttribute.MapToName;
                }
                else
                {
                    return entityType.Name.ToLowerInvariant();
                }
            }
            return base.ResolvePropertyName(propertyName);
        }
    }
}

Note: as I’m developing portable library(PCL) with C#6 you may notice little changed reflection call with entityType.GetTypeInfo()
Now for deserializing I call:

    JsonSerializerSettings settings = new JsonSerializerSettings()
    {
        ContractResolver = new ApiEntities.Base.EntityContractResolver<User>()
    };
    var deserialized = JsonConvert.DeserializeObject<ApiEntities.Base.Answer<User>>(jsonAnswer, settings);

That’s all. If you know how this could be implemented easier, then leave your thoughts in comments please.

Trip to json

json160

Not so far I figured for myself out, that json isn’t just an interchange data format. It grows with days and become more and more similar to XML. Before “Not so far” I have faced only with jsonp, which is used for XSS’es.

At this time I found out, that there is such stuff like:

  • JSONRequest – library with 4 functions(post, get, clear, cancel), which is used for safe XSS-requesting by excluding all headers and cookies, cause they usually contains sensitive data
  • JSON-RPC, which is similar to XML-RPC protocol
  • JSONPath – analogue of XPath but for json
  • JSON Schema – analogue of XSD

So for now is missed 1 important part from these JSON–XML stack – XSLT. Within 5 minutes in google I found 2 implementatios of such functionallity for json: JSONT(js) and JOML(java). I suppose we might see soon some more official and specified implementation for json transformation technology.