Управление целевым объектом раскадровки - PullRequest
1 голос
/ 24 марта 2010

В обработчике для Completed события Storyboard как получить элемент, к которому применяется раскадровка?

Моя Раскадровка является частью ItemTemplate:

<ListBox x:Name="MyListBox" >
    <ListBox.ItemTemplate>
        <DataTemplate>
            <Grid x:Name="Container" Height="30" >
                <Grid.Resources>
                    <Storyboard x:Name="FadeOut" BeginTime="0:0:7"  Completed="FadeOut_Completed">
                        <DoubleAnimation From="1.0" To="0.0" Duration="0:0:3" Storyboard.TargetName="Container" Storyboard.TargetProperty="Opacity" />
                    </Storyboard>
                </Grid.Resources>

                [...snip...]

            </Grid>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

в событии Completed я хочу взять сетку с именем Container , чтобы я мог делать неприятные вещи с его DataContext. Можно ли это сделать, или я поступаю неправильно?

Спасибо:)

1 Ответ

2 голосов
/ 13 апреля 2010

Ответ на этот вопрос заключается в том, что это невозможно - во всяком случае, не в Silverlight 3.

Используя отладчик, я смог найти приватное свойство Storyboard, которое, когда я прошел по дереву объектов, попал в содержащий элемент шаблона - однако я не мог коснуться этого из кода, используя отражение из-за ограничений безопасности размещается на приложениях Silverlight (хотя это вполне возможно в WPF).

Мое возможное решение заключалось в использовании Dictionary<Storyboard, Grid> и нескольких обработчиков событий. С шаблоном, к которому я прикрепил обработчик Loaded, это означает, что мой обработчик вызывается каждый раз, когда создается и загружается экземпляр шаблона (то есть для каждого элемента данных, который связан со списком). На данный момент у меня есть ссылка на физический экземпляр шаблона, поэтому я могу искать его дочерние элементы для раскадровки:

private void ItemTemplate_Loaded(object sender, RoutedEventArgs e)
{
    Storyboard s = getStoryBoard(sender);
    if (s != null)
    {
        if (!_startedStoryboards.ContainsKey(s))
            _startedStoryboards.Add(s, (Grid)sender);
    }
}

private Storyboard getStoryBoard(object container)
{
    Grid g = container as Grid;
    if (g != null)
    {
        if (g.Resources.Contains("FadeOut"))
        {
            Storyboard s = g.Resources["FadeOut"] as Storyboard;
            return s;
        }
    }
    return null;
}

private Dictionary<Storyboard, Grid> _startedStoryboards = new Dictionary<Storyboard, Grid>();

Затем, когда запускается событие раскадровки Completed, я могу легко использовать этот словарь в качестве поиска для получения шаблона элемента, в котором он размещен, и оттуда я могу получить DataContext шаблона элемента и выполнить неприятные вещи, которые я планировал:

private void FadeOut_Completed(object sender, EventArgs e)
{
    if (_startedStoryboards.ContainsKey((Storyboard)sender))
    {
        Grid g = _startedStoryboards[(Storyboard)sender];
        if (g.DataContext != null)
        {
            MyDataItem z = g.DataContext as MyDataItem;

            if (z != null)
            {
                ... do my thing ...
            }
        }
    }
}

[Примечание: этот код был санирован для публичного просмотра, извините за любые небольшие расхождения или синтаксические ошибки, которые вы можете заметить]

...