을 들고 이벤트를 화재에 손길이 닿지 않은 품목에서 ListView
-
21-12-2019 - |
문제
나 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 도록 강요하는 이동을 사용하여 그 내용을 정렬.
이 문제는 해야 할 가상화?어떻게 이 문제를 해결할 수 있을까요?
대안을 할 것입니다.
업데이트:
일부 제안 게시물을 재활용 모드를 발생 항목은 다시 사용할 수 있습니다.가
VirtualizingStackPanel.VirtualizationMode="Standard"
내 ListView 그러나 문제는 놀랍게도 지속됩니다.
그래서 지금 내가 위에 그림을 방지하는 방법이 다른 항목에서 반복되는 동일한 투명도 값(아된 때문에 그것은 세트를 통해 스토리 보드).
업데이트 2:
지금 설명하는 페이드에에 들고 표시된 항목은 완전히 사라질 때가 view:
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
해결책
내가 좋아하는 방법 당신이 시도하고 있는지 여기에.터치 스크린 장치에,우리는 없다 MouseOver
이벤트므로 이것은 하나의 방법으로 표시하려면 몇 가지 추가 정보 없이 엉망으로 UI.
그러나,많은 청소기 솔루션을 생성,재사용할 수 있는 Behavior
캡슐화하는 모든 UI 논리 및 애니메이션.
이렇게하려면,당신은 당신이 먼저 해야를 포함 참조 Behaviors SDK (XAML)
.
이 Behavior
구현은 바로 사용할 수 있도록되어있다.이 AssociatedObject
이 될 것입 Grid
를 수신하는 터치 이벤트 그리고 당신을 만들어야 DependencyProperty
TextBlockName
검색 설명 TextBlock
인스턴스입니다.일단 인스턴스를 작성해야에 대한 애니메이션에서는 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;
}
}
이 Behavior
할 수 있습 첨부 DataTemplate
아 최고 수준 Grid
.참고는 당신이 필요하지 않습 UserControl
포장됩니다.
또한,당신이 있는지 확인 배경 색상 Grid
그래서 그것을 받을 수 있는 터치합니다.마지막 일을 했을 변경할 ListView
ko ItemContainerStyle
ko HorizontalContentAlignment
하기 Stretch
그래서 Grid
으로 모든 방법을 통해 오른쪽에 있습니다.
<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
내 모델 설정의 기본값 0
할 때 추가하는 새로운 항목을 나 ObservableCollection
내 뷰 모델.
또한 추가한 2-바인딩 방법 원본을 변경하산(DescriptionLayerOpacity
하)으로 보기를 얻 업데이트와 변경 사항에 의해 만들어진 스토리 보드:
<Grid ... Opacity="{Binding DescriptionLayerOpacity, Mode=TwoWay}">
<TextBlock .../>
</Grid>
간단히 말해서,모든 정렬 데이터를된 것을 방지하고 반복에 다른 항목이 ListView.
이것은 정말 아닙니다 우아한 솔루션과되지 않은 완벽하게 테스트됩니다.를 찾을 때까지 실제 솔루션,이 충분합니다.
업데이트:지 않은 완벽하게 작업
나는 최근에 발견되는 몇 가지 항목은 응답하지 않을 때 다른 항목이 선택됩니다.그 항목을 얻을 응답으로 가기 전에 꼭+이벤트를 개최(두는 상호 배타적인 행사 방법에 의해).
Update2:
모든 것을 할 수있는 후에 제거 if
문 코드 숨김.그러나 바인딩을 불투명 재산 모델에서 그것을 얻을 작품은 여전히 냄새 나는 솔루션입니다.
나는 확실하지 않으면 이것은 정확하게 당신의 문제이지만,그 소리와 같은 UserControl
지 않을 받기 이벤트를 개최기 때문에 흡수되는 것에 ListView
?이 솔루션은 위에서 설명할 필요 포장 DataTemplates
Grid
에 ListViewItem
, 고를 연결하는 이벤트를 개최한다.어쩌면 이것은 도움이 되나요?