Tooltip Data Binding в Silverlight. Версия для печати 11/08/08

Как вы знаете в MS WPF, ну и соответственно в Silverlight невероятно просто отделить данные приложения от их представления. Достаточно написать что-то вроде:

<ListBox  x:Name="Cities" ItemsSource="{Binding Items}" />

и дело в шляпе. DataContext автоматически пробрасывается по Logic Tree. Но к сожалению эта стратегия не срабатывает при попытке прибиндить данные к ToolTip. Например, казалось бы такой логичный код:

<HyperlinkButton
   Content="{Binding Name}"
   Tag="{Binding Id}"
   ToolTipService.ToolTip="{Binding PopupInfo}" 
/>

работать не будет. Все дело в том что, всплывающая подсказка ToolTipService.ToolTip находится за пределами Logic Tree и ей ни какого Data Context не передается!

Решить проблему можно с помощью Attached Properties! Это мощнейшая технология напоминает аспектно-ориентированное программирование и открывает просто невероятные возможность по расширению функционала существующих объектов без наследования или агрегирования последних.

Реализуем простое attached property, который будет подключать data context к объекту - всплывающей подсказке:

public class Helpers {

  public static string GetToolTipContent(DependencyObject obj) {
    return (string)obj.GetValue(ToolTipContentProperty);
  }

  public static void SetToolTipContent(DependencyObject obj,
                                        string value) {
     obj.SetValue(ToolTipContentProperty, value);
  }

  public static readonly DependencyProperty
  ToolTipContentProperty =
    DependencyProperty.RegisterAttached(
      "ToolTipContent",
      typeof(string),
      typeof(Helpers),
      new PropertyMetadata(OnToolTipContentChangedCallback));

  private static void OnToolTipContentChangedCallback(
     DependencyObject d, DependencyPropertyChangedEventArgs e) {
    var tt = (ContentControl)ToolTipService.GetToolTip(d);
    tt.Content = e.NewValue.ToString();
    ToolTipService.SetToolTip(d, tt);
  }
}

А в XAML соответсвенно его будем использовать:

xmlns:service="clr-namespace:Service"
...
<HyperlinkButton
   Content="{Binding Name}"
   Tag="{Binding Id}"
   service:Helpers.ToolTipContent="{Binding PopupInfo}"
>
   <ToolTipService.ToolTip>
      <ToolTip Style="{StaticResource NewToolTip}" />
   </ToolTipService.ToolTip>
</HyperlinkButton>

вот и вся уличная магия! Мысль о применении attached property пришла после прочтения этой заметки Nikhil Kothari. Классное имя Нехилл :)

| Комментарии

Кредитный калькулятор на Silverlight. Версия для печати 30/07/08

Решил написать что-нибудь полезное на Silverlight! Этим полезным оказался калькулятор аннуитетных платежей.

Напомню (или расскажу тому, кто еще не знаком) что существует две схемы выплат по кредиту: дифференцированная и аннуитетная. В первом случае кредит выплачивается различными по величине суммами, но с фиксированной суммой погашения основного долга. Платежи различаются на сумму процентов на остаток долга. Получается, что в начале выплат вы платите самые большие суммы, а в конце самые маленьки. Напротив - при аннуитетной схеме кредит выплачивается равными частями каждый период, а части основного долга и процентов в каждом платеже отличаются. Платежи устроены так, что в начале выплат большая часть их идет на погашение процентов по кредиту, а уже потом в зачет суммы основного долга. Не следует однозначно судить какая из схем лучше, но на рынке в основном преобладает вторая схема. Для банков она выгодна тем, что кредитор получает больший процент и может кредитовать на большую сумму отдельного клиента. Для клиентов аннуитет выгоден тем, можно взять большую сумму на больший срок. К слову сказать, не смотря на то, что сумма процентов при аннуитетной схеме больше, если при погашении кредита каждый раз выплачивать одинаковую долю основного долга (как при дифференцированной схеме), то сумма процентов будет той же что и в первой схеме.

Банки используют несколько формул расчета аннуитетных платежей но результат не сильно различается. В своем калькуляторе я использовал эту формулу.

Ничего сверхъестественного пример, не демонстрирует (более того - вся его красота внутри), но надеюсь будет полезен. К сожалению так и не придумал куда прикрутить анимацию - поэтому обещаю в скором времени набросать пример позавлекательнее :)

P.S.Обратите внимание на внешний вид таблицы! К ней применены собственные стили. Стили по-умолчанию не сложно выдрать с помощью .NET Reflector из дистрибутива SilverLight (хорошо что они не обфускачины):

Lutz Roeder's .NET Reflector

| Комментарии [4]

Снова о blur в Silverlight. Версия для печати 24/06/08

Неделю назад я подумал, что хорошо бы реализовать идею Dave Relyea с помощью Attached DependencyProperties. Когда, как вчера гуру Dave Relyea запостил соответствующий пост.

Результат работы алгоритма для моего примера в виде картинки не изменился:

Blur в Silverlight. Часть 2

Работающий пример здесь. Архив примера здесь. Собственно код:

<UserControl
   x:Class="SilverlightImageBlur.Page"
   xmlns="http://schemas.microsoft.com/client/2007"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   xmlns:local="clr-namespace:SilverlightImageBlur"
   Width="Auto" Height="Auto"
>
   <StackPanel>
      <Border
         BorderThickness="1" BorderBrush="#FF000000"
         HorizontalAlignment="Center" Margin="0,10,0,0">
         <StackPanel Orientation="Horizontal">
            <Image Stretch="None" Margin="5"
               Source="SilverlightImageBlur;
               component/page-first.png"/>
            <Image Stretch="None" Margin="5"
               Source="SilverlightImageBlur;
               component/page-prev.png"/>
            <Image Stretch="None" Margin="5"
               Source="SilverlightImageBlur;
               component/page-next.png"/>
            <Image Stretch="None" Margin="5"
               Source="SilverlightImageBlur;
               component/page-last.png"/>
         </StackPanel>
      </Border>
      <TextBlock Text="Blur..." HorizontalAlignment="Center"
         FontFamily="Verdana" FontSize="12" Margin="5" />
      <Border
         BorderThickness="1" BorderBrush="#FF000000"
         Margin="0,0,0,0" HorizontalAlignment="Center"
         local:PixelSnapBehavior.PixelSnap="Closest" >
         <StackPanel Orientation="Horizontal">
            <Image Stretch="None" Margin="5"
               Source="SilverlightImageBlur;
               component/page-first.png"/>
            <Image Stretch="None" Margin="5"
               Source="SilverlightImageBlur;
               component/page-prev.png"/>
            <Image Stretch="None" Margin="5"
               Source="SilverlightImageBlur;
               component/page-next.png"/>
            <Image Stretch="None" Margin="5"
               Source="SilverlightImageBlur;
               component/page-last.png"/>
         </StackPanel>
      </Border>
   </StackPanel>
</UserControl>

| Комментарии

« Предыдущая страница
» Следующая страница

Последние статьи

Opml.xml

Rss

About

MeМеня зовут Денис Ларионов.
Работаю программистом. Мне есть что рассказать про: web-бизнес, маркетинг, программирование.

RSS

Я - Слушаю подкаст Radio-T