views:

609

answers:

4

Is it possible to localize DataPager's footer (Page X of Y) in Silvelright?

The strings seem to be located in resources embedded in the assembly of DataPager. So how should I localize it?

Unfortunately, almost nothing in the DataPager class is virtual and also many internal classes are used by it, so it is not possible (at least easily) to inherit DataPager and override the behavior.

A: 

The only solution I've found out so far is to edit the template of DataPager, remove the two textboxes responsible for displaying "Page" and "of X" and create new ones. Then, inherit DataPager, override OnApplyTemplate to attach to your new TextBoxes.

The last part is the trickiest - you have to handle proper events of your datasource (it depends on the datasource) and update text of your new textboxes.

Although this solution should work, it is not very nice...

gius
A: 

So, there is another solution - changing the resources in the DLL.

The solution is based on this article.

Since the System.Controls.Data.dll is signed by MS, I needed to remove the signature (strong name). I used AdmiralDebilitate to remove it.

  1. Copy System.Controls.Data.dll to a temp folder.
  2. Use AdmiralDebilitate to open the dll, click Mark All and then Apply changes. This should remove the strong name that would prevent the patched dll with custom resources to work.
  3. Open Visual Studio Command Prompt in the temp folder.
  4. Disassemble the dll by command

    ildasm /out=System.Controls.Data.il System.Controls.Data.dll

  5. Use any resource editor (I used Resource.net) to open System.Windows.Controls.DataPager.PagerResources.resources.

  6. Edit the resource strings you want. Save the resource file and close the editor.
  7. Reassemble the assembly by command

    ilasm /resource=System.Controls.Data.res /dll /output=System.Controls.Data.dll System.Controls.Data.il

  8. Done.

There are two possible problems:

  • You must make sure that VS uses this DLL and not the original one from GAC. This can be ensured by opening the .csproj file in notepad and checking the reference path.
  • If you use any other MS assemblies that are dependent on the patched one, you will need to patch them too (AdmiralDebilitate should help).
gius
+1  A: 

That's pretty simple. See how I localized DataPager for Portuguese language:

using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace MarceloOliveira.Controls
{
/// <summary>
/// Customização feita sobre o Data Pager padrão do Silverlight, para traduzir para o português
/// </summary>
public class CustomDataPager : DataPager
{
    TextBlock currentPagePrefixTextBlock;
    TextBlock currentPageSuffixTextBlock;
    TextBox currentPageTextBox;

    public CustomDataPager() : base()
    {
        this.PageIndexChanged += new EventHandler<EventArgs>(CustomDataPager_PageIndexChanged);
        this.MouseLeftButtonDown += new MouseButtonEventHandler(CustomDataPager_MouseLeftButtonDown);
    }

    public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();
        currentPagePrefixTextBlock = GetTemplateChild("CurrentPagePrefixTextBlock") as TextBlock;
        currentPageSuffixTextBlock = GetTemplateChild("CurrentPageSuffixTextBlock") as TextBlock;
        currentPageTextBox = GetTemplateChild("CurrentPageTextBox") as TextBox;
        currentPageTextBox.TextChanged += new TextChangedEventHandler(currentPageTextBox_TextChanged);
        currentPageSuffixTextBlock.SizeChanged += new SizeChangedEventHandler(currentPageSuffixTextBlock_SizeChanged);
    }

    void currentPageTextBox_TextChanged(object sender, TextChangedEventArgs e)
    {
        TranslateLabels();
    }

    void CustomDataPager_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        TranslateLabels();
    }

    void CustomDataPager_PageIndexChanged(object sender, EventArgs e)
    {
        TranslateLabels();
    }

    void currentPageSuffixTextBlock_SizeChanged(object sender, SizeChangedEventArgs e)
    {
        TranslateLabels();
    }

    private void TranslateLabels()
    {
        if (currentPagePrefixTextBlock != null)
        {
            currentPagePrefixTextBlock.Text = "Pág.";
            currentPageSuffixTextBlock.Text = string.Format("de {0}", this.PageCount);
        }
    }
}

}

Marcelo Oliveira
A: 

Just add the cultures you need to the SupportedCultures element in the project file, e.g.

<SupportedCultures>en,de</SupportedCultures>

Now the DataPager uses German resources on German computers.

Stefan Lange
Unfortunately, this does not work for me. I guess the reason is that simply there are no other resources other than English in the assembly.
gius