質問

UserControlイベントに加入しているGridを持つHoldingを持ちます。問題は、Holdingイベントがターゲットとされている項目がListView内の他の項目に対して発行されることです。ところでDataTemplateとしてコントロールを使用しています。

<ListView ItemsSource="{Binding ...}" Margin="0, 0, 0, 0">
    ...
    <ListView.ItemTemplate>
        <DataTemplate>
            <local:MyUserControl/>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>
.

ユーザ制御コード後ろ:

    private bool isDescriptionVisible = false;

    private void Grid_Holding(object sender, HoldingRoutedEventArgs e)
    {
        if (!isDescriptionVisible)
        {
            DescriptionFadeIn.Begin();
            isDescriptionVisible = true;
        }
    }

    private void Grid_Tapped(object sender, TappedRoutedEventArgs e)
    {
        if (isDescriptionVisible)
        {
            DescriptionFadeOut.Begin();
            isDescriptionVisible = false;
        }
    }
.

ユーザ制御内容:

<Grid.Resources>
    <Storyboard x:Name="FadeIn">
            <DoubleAnimation Storyboard.TargetProperty="Opacity" Storyboard.TargetName="DescriptionLayer"
                             Duration="0:0:0.3" To=".8"/>
        </Storyboard>

        <Storyboard x:Name="FadeOut">
            <DoubleAnimation Storyboard.TargetProperty="Opacity" Storyboard.TargetName="DescriptionLayer"
                             Duration="0:0:0.3" To="0"/>
        </Storyboard>
</Grid.Resources>

<Grid Margin="0, 0, 0, 48" Holding="Grid_Holding" Tapped="Grid_Tapped">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="1*"/>
    </Grid.RowDefinitions>
    <Image Source="{Binding Img}" Stretch="UniformToFill" Height="240" Width="450"/>
    <Grid x:Name="DescriptionLayer" Background="Black" Opacity="0">
        <TextBlock Text="{Binding Description}" FontSize="16" TextWrapping="Wrap" Margin="0, 9, 0, 0" MaxHeight="170" TextTrimming="CharacterEllipsis"/>
    </Grid>
    <StackPanel Grid.Row="1" Margin="12">
        <TextBlock Text="{Binding Author}" FontSize="16"/>
        <TextBlock Text="{Binding Title}" FontSize="18"/>
    </StackPanel>
</Grid>
.

DataTemplateに含まれているアイテムでストーリーボードを使用できませんでしたので、その内容をUserControlに使用することを強制しました。

この問題は仮想化と関係がある必要がありますか?どうすればいいですか?

代替案は行います。

更新

その他の投稿は、リサイクルモードがアイテムを再利用することを提案した。私は追加しました 私のListViewへのVirtualizingStackPanel.VirtualizationMode="Standard"しかし、問題は驚くほど持続します。

今度は、他の項目が同じ不透明度の値を繰り返すのを防ぐ方法を理解する必要があります(ストーリーボードを介して設定されているため、データバウンドではありません)。

更新2

現在表示されているアイテムを保持しているときにフェードインすると、視聴不能になると完全に消えます。

<ItemsControl.ItemsPanel>
    <ItemsPanelTemplate>
        <VirtualizingStackPanel/>
    </ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
.

役に立ちましたか?

解決

私はあなたがここでやろうとしているのを目指しているのが好きです。タッチスクリーンデバイスの場合、MouseOverイベントはありませんので、UIをめちゃくちゃにすることなくいくつかの追加情報を表示したい場合の方法の1つです。

しかし、すべてのUIロジックとアニメーションをカプセル化する再利用可能なBehaviorを作成するには、はるかにクリーンなソリューションがあります。

これを行うために、最初に参照Behaviors SDK (XAML)を含める必要があります。

Behaviorの実装は簡単です。 AssociatedObjectは、タッチイベントを受信し、次に説明Gridインスタンスを取得するためにDependencyProperty TextBlockNameを作成する必要があります。インスタンスがあると、C#。

でアニメーションを書く必要があります。
public class ShowHideDescriptionBehavior : DependencyObject, IBehavior
{
    public string TextBlockName
    {
        get { return (string)GetValue(TextBlockNameProperty); }
        set { SetValue(TextBlockNameProperty, value); }
    }

    // Using a DependencyProperty as the backing store for TextBlockName.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty TextBlockNameProperty =
        DependencyProperty.Register("TextBlockName", typeof(string), typeof(ShowHideDescriptionBehavior), new PropertyMetadata(string.Empty));

    public DependencyObject AssociatedObject { get; set; }

    public void Attach(DependencyObject associatedObject)
    {
        this.AssociatedObject = associatedObject;
        var panel = (Panel)this.AssociatedObject;

        panel.Holding += AssociatedObject_Holding;
        panel.Tapped += AssociatedObject_Tapped;
    }

    private void AssociatedObject_Tapped(object sender, Windows.UI.Xaml.Input.TappedRoutedEventArgs e)
    {
        var animation = new DoubleAnimation
        {
            Duration = TimeSpan.FromMilliseconds(300),
            To = 0
        };
        Storyboard.SetTarget(animation, this.DescriptionTextBlock);
        Storyboard.SetTargetProperty(animation, "Opacity");

        var storyboard = new Storyboard();
        storyboard.Children.Add(animation);
        storyboard.Begin();
    }

    private void AssociatedObject_Holding(object sender, Windows.UI.Xaml.Input.HoldingRoutedEventArgs e)
    {
        var animation = new DoubleAnimation
        {
            Duration = TimeSpan.FromMilliseconds(300),
            To = 0.8
        };
        Storyboard.SetTarget(animation, this.DescriptionTextBlock);
        Storyboard.SetTargetProperty(animation, "Opacity");

        var storyboard = new Storyboard();
        storyboard.Children.Add(animation);
        storyboard.Begin();
    }

    private TextBlock _descriptionTextBlock;
    private TextBlock DescriptionTextBlock
    {
        get
        {
            if (_descriptionTextBlock == null)
            {
                var panel = (Panel)this.AssociatedObject;
                // todo: add validation
                _descriptionTextBlock = (TextBlock)panel.FindName(this.TextBlockName);
            }

            return _descriptionTextBlock;
        }
    }

    public void Detach()
    {
        var panel = (Panel)this.AssociatedObject;

        panel.Holding -= AssociatedObject_Holding;
        panel.Tapped -= AssociatedObject_Tapped;
    }
}
.

このTextBlockは、Behaviorの最上位のDataTemplateに接続できます。もう包むためのGridを必要としないことに注意してください。

また、UserControlの背景色があるため、タッチイベントを受信できるようにしてください。私がした最後のことは、GridListViewItemContainerStyleに変更することでしたので、HorizontalContentAlignmentが右側にずっと伸びるようにします。

<Page.Resources>
    <DataTemplate x:Key="GroupTemplate">
        <Grid Background="Transparent" Margin="12">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>
            <Interactivity:Interaction.Behaviors>
                <local:ShowHideDescriptionBehavior TextBlockName="Description" />
            </Interactivity:Interaction.Behaviors>
            <Border Background="{StaticResource ListViewItemPlaceholderBackgroundThemeBrush}" Width="110" Height="110">
                <Image Source="{Binding Img}" Height="110" Width="110"/>
            </Border>
            <StackPanel Grid.Column="1" Margin="10,0,0,0">
                <TextBlock Text="{Binding Author}" Style="{StaticResource TitleTextBlockStyle}"/>
                <TextBlock x:Name="Description" Opacity="0" Text="{Binding Description}" Style="{StaticResource CaptionTextBlockStyle}" TextWrapping="NoWrap"/>
            </StackPanel>
        </Grid>
    </DataTemplate>
</Page.Resources>

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" DataContext="{Binding Source={StaticResource SampleDataSource}}">
    <ListView ItemTemplate="{StaticResource GroupTemplate}" ItemsSource="{Binding Groups}">
        <ListView.ItemContainerStyle>
            <Style TargetType="ListViewItem">
                <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
            </Style>
        </ListView.ItemContainerStyle>
    </ListView>
</Grid>
.

他のヒント

私は回避策を見つけました。 DescriptionLayerOpacityというプロパティをMy Modelに追加し、私のViewModelの0に新しい項目を追加しているときにそれを既定値に設定しました。

ソースプロパティ(ObservableCollection)を変更するための2方向バインディングを追加して、ストーリーボードによって行われた変更で更新されるようにしてください。

<Grid ... Opacity="{Binding DescriptionLayerOpacity, Mode=TwoWay}">
    <TextBlock .../>
</Grid>
.

Nutshellでは、ListViewの他の項目で繰り返されるのを防ぐために、すべてのUserControlのデータをデータバインドしなければなりませんでした。

これは本当に優雅な解決策ではなく、完全にテストされていません。実際の解決策が見つかるまで、これは十分です。

アップデート:完全に機能しない

私は最近、他の項目が選択されている場合には何らかのアイテムが応答しないことを発見しました。これらの項目を応答するには、TAP + HOLDイベントの前にタップする必要があります(どちらも相互に排他的なイベントは、ところで)。

アップデート2:

CodeBehindのDescriptionLayerOpacityステートメントを削除した後、すべてがうまく機能しているようです。しかし、それを仕事にするためにモデル内の不透明性プロパティへのバインディングはまだ臭いのある解決策です。

ここでの解決策を見てください。 http://social.msdn.microsoft.com/forums/windowsapps/en-us/95f49050-368e-4ddb-962e-6be62e7e3d57/CONTEXT-MENUS-IN-LISTVIEW-Windows-Phone-81?Forum= WPDevelop

これが正確に問題であるかどうかわからないが、UserControlによって吸収されるので、ListViewが保留イベントを受信していないように聞こえます。 上記の解決策では、DataTemplatesGrid ListViewItemをラップし、ホールドイベントをそれに接続する必要があります。多分これは役に立ちますか?

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top