Анимация CustomUserControl, созданного во время выполнения - PullRequest
0 голосов
/ 26 мая 2020

Проблема, с которой я столкнулся, заключается в том, что, когда я начинаю раскадровку, она меняет значение в объекте, как ожидалось, но не видно анимации. Во время работы раскадровки ничего не происходит, затем, когда это будет сделано, объект мгновенно получит окончательный результат раскадровки (используя HoldEnd). Продолжительность раскадровки в основном действует как задержка.

  • Я использую Scrollviewer с Stackpanel для отображения списка анимированных пользовательских элементов управления. Эти элементы имеют высоту 28 пикселей и содержат кнопки для развертывания и свертывания разделов, содержащих данные.
  • Элементы создаются при получении события в моем MainWindow и добавляются в Scrollviewer с использованием scrData.Dispatcher.Invoke(()=>{}).

Я подозреваю, что проблема может быть в потоке, который владеет этими элементами управления. Поскольку они созданы в методе диспетчера Scrollviewer, означает ли это, что поток пользовательского интерфейса владеет ими или поток, который запустил событие, владеет ими?

Я использовал в основном тот же код для анимации вещей раньше, поэтому единственная реальная разница в том, что эти элементы управления были созданы во время выполнения.

Любая помощь будет принята с благодарностью :)

Вот соответствующие биты моего кода:

MainWindow.cs: (получение данных, создание элемента):

    private void DataPoller_Update(object sender, DataPollerEventArgs e)
    {
        //New Data arrives here
        if (e.message == "results")
        {
            DisplayData(e.data);
        }
    }


    public void DisplayData(List<DataItem> data){
        scrData.Dispatcher.Invoke(() => {
            int i = 0;
            foreach (DataItem item in data) {
                if (IsInCurrentList(item.id)) {
                    Update_ExistingItemInfo(item);
                }
                else {
                    //Add new item to StackPanel
                    CustomControls.data_item newItem = new CustomControls.data_item(item);
                    stkData.Children.Insert(i, newItem);
                }
                i++;
            }
        }
    }

Из .cs UserControl:

    DataItem data;

    public data_item(DataItem newData)
    {
        InitializeComponent();
        data = newData;
        PopulateDataFields();
        //THESE ROWS SHOULD EXPAND OR COLLAPSE ON btnExpand_Click
        grdMain.RowDefinitions[1].Height = new GridLength(0);
        grdMain.RowDefinitions[2].Height = new GridLength(0);
    }
     private void btnExpand_Click(object sender, RoutedEventArgs e)
     {
         //For some reason, can't find reference to sb_Expand directly.
        btnExpand.Dispatcher.Invoke(()=> {
            if (rowDrilldown.ActualHeight > 0) {
                Storyboard sb = (Storyboard)this.Resources["sb_Collapse"];
                sb.Begin();
                }
            else {
                Storyboard sb = (Storyboard)this.Resources["sb_Expand"];
                sb.Begin();
                } 
        });
     }

Из xaml UserControl:

    <UserControl.Resources>
            <Storyboard x:Key="sb_Expand">
                <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(RowDefinition.Height)" Storyboard.TargetName="rowDrilldown" BeginTime="0" FillBehavior="HoldEnd">
                    <DiscreteObjectKeyFrame KeyTime="0:0:0">
                        <DiscreteObjectKeyFrame.Value>
                            <GridLength>0</GridLength>
                        </DiscreteObjectKeyFrame.Value>
                    </DiscreteObjectKeyFrame>
                    <DiscreteObjectKeyFrame KeyTime="0:0:0.25">
                        <DiscreteObjectKeyFrame.Value>
                            <GridLength>400</GridLength>
                        </DiscreteObjectKeyFrame.Value>
                    </DiscreteObjectKeyFrame>
                </ObjectAnimationUsingKeyFrames>
            </Storyboard>
            <Storyboard x:Key="sb_Collapse">
                <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(RowDefinition.Height)" Storyboard.TargetName="rowDrilldown" BeginTime="0" FillBehavior="HoldEnd">
                    <DiscreteObjectKeyFrame KeyTime="0:0:0">
                        <DiscreteObjectKeyFrame.Value>
                            <GridLength>400</GridLength>
                        </DiscreteObjectKeyFrame.Value>
                    </DiscreteObjectKeyFrame>
                    <DiscreteObjectKeyFrame KeyTime="0:0:0.25">
                        <DiscreteObjectKeyFrame.Value>
                            <GridLength>0</GridLength>
                        </DiscreteObjectKeyFrame.Value>
                    </DiscreteObjectKeyFrame>
                </ObjectAnimationUsingKeyFrames>
            </Storyboard>
        </UserControl.Resources>

        <Border BorderBrush="AliceBlue" BorderThickness="1" CornerRadius="4">
            <Grid x:Name="grdMain">
                <Grid.RowDefinitions>
                    <RowDefinition Height="28"/>
                    <RowDefinition Height="165"/>
                    <RowDefinition x:Name="rowDrilldown" Height="400"/>
                </Grid.RowDefinitions>
                <!--Textboxes and other CustomControls-->
            </Grid>
        </Border>

1 Ответ

0 голосов
/ 30 мая 2020

Нашел более простой способ сделать это с помощью VisualStateManager:

<Storyboard x:Key="sb_Expand">
            <DoubleAnimationUsingKeyFrames  Storyboard.TargetProperty="Height" Storyboard.TargetName="scrDrilldown" FillBehavior="HoldEnd">
                <EasingDoubleKeyFrame KeyTime="0:0:0" Value="0"/>
                <EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="390"/>
            </DoubleAnimationUsingKeyFrames>
</Storyboard>

.

<Grid x:Name="grdMain">
                <VisualStateManager.VisualStateGroups>
                    <VisualStateGroup x:Name="grdMain_VSG">
                        <VisualState x:Name="ExpandItem" Storyboard="{StaticResource sb_Expand}"/>
                        <VisualState x:Name="CollapseItem" Storyboard="{StaticResource sb_Collapse}"/>
                    </VisualStateGroup>
                </VisualStateManager.VisualStateGroups>

// при нажатии кнопки:

bool tmp = ExtendedVisualStateManager.GoToElementState(this.grdMain as FrameworkElement, "ExpandItem", true);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...