Q:

How to filter items by language in Treelist field

On a multilingual site, how can I make a treelist field to only show items of selected language in the editor -so editors can't select items that do not have versions or shouldn't exist on their site. 
We are needing this for a "taxonomy" field but some (could be lots) of them will only apply to specific language versions.
Is there a way to modify existing treelist so it can achieve this? Or if the answer is to create a new one, what should I override? Can't figure out what to modify.

A:

There's already answer to similar problem on Stack Overflow: https://stackoverflow.com/questions/21452260/sitecore-tree-list-datasource-versionexist
In a nutshell, what you need to do:
Create DataView which will be responsible for filtering non-existing items
LanguageFilteringMasterDataView : MasterDataView

Override method GetChildItems where you can filter out non-existing items
protected override void GetChildItems(ItemCollection items, Item item)

Register data view in configuration under dataviews node
<dataviews>
    <dataview name="LanguageFilteredMaster" assembly="sc70" type="sc70.Controls.LanguageFilteringMasterDataView" Parameters=""/>
</dataviews>

and finally create custom TreeList control which will inherit from TreeList and connect your data view there
public class LanguageFilteringTreelist : TreeList
{
    private const string DataViewName = "LanguageFilteredMaster";

    protected override void OnLoad(EventArgs args)
    {
        base.OnLoad(args);
        var dataContext = this.FindDataContext();
        if (dataContext != null)
        {
            dataContext.DataViewName = DataViewName;
        }
    }

    protected virtual DataContext FindDataContext()
    {
        if (this.Controls.Count <= 0)
        {
            return null;
        }

        var child = this.Controls[0];
        return child.Controls.OfType<DataContext>().FirstOrDefault();
    }
}

UPDATES from @josedbaez

The solution works on 8.1. The only difference from the original answer (so others know) is the javascript code. You do not need to make that change anymore as Sitecore now appends selected language to html like: <input id="FIELD9318757_all_Language" type="hidden" value="en-CA"> <input id="FIELD9318757_all_Language" type="hidden" value="en-CA">
Do not forget to register your new field type as MultilistField to the <fieldtypes> configuration (Found in "App_Config/FieldTypes.config" by default) so that the items referenced by the field are added to Link Database.
e.g. <fieldType name="LanguageFilteringTreelist" type="Sitecore.Data.Fields.MultilistField,Sitecore.Kernel" />

A:

In case anyone wants another solution. Viacheslav from Sitecore support suggested the following which is copying existing Treelist code and adding IDs of unwanted items to the ExcludeItemsForDisplay property. I find Szymon/Ben Golden solution to be more elegant but no harm in having multiple options.
Solution

Create a class for your custom field. Use a disassemble tool to get and copy the original code of TreeList class Sitecore.Shell.Applications.ContentEditor.TreeList in Sitecore.Kernel.dll
Create a method in this class which will add the IDs of items without versions in the ExcludeItemsForDisplay property. This method should be called before FormTemplateFilterForDisplay method. Note: Multiple IDs should be separated by , e.g. {110D559F-DEA5-42EA-9C1C-8A5DF7E70EF9},{EB2E4FFD-2761-4653-B052-26A64D385227}
Create your own field type in core database:

e.g. Create item under: /sitecore/system/Field types/Link Types/ MyTreeList with base template /sitecore/templates/System/Templates/Template field type
Set your Namespace.ClassName and assembly name in the Assembly and Class fields

Change field type in your template from the TreeList to the newly added field type.

