英文:
Why doesn't frame change its background?
问题
我在首页上有一个CollectionView。CollectionView元素由一个Frame作为容器和其他元素组成(请参见下面的代码)。我想在CollectionView中选中Frame时实现更改Frame的颜色,但VisualStateManager "不起作用"。在这种方法中,我如何添加Frame动画当我选择它时?
我的ContentPage.Resources代码:
<ContentPage.Resources>
<Style TargetType="Frame">
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="Selected">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="Red" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
</ContentPage.Resources>
我的CollectionView代码:
<CollectionView.ItemTemplate>
<DataTemplate>
<Frame Margin="10, 10, 10, 0"
HeightRequest="100"
MinimumHeightRequest="95"
Padding="13"
CornerRadius="20"
BackgroundColor="DodgerBlue"
BorderColor="Transparent">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Label
Text="{Binding Title}"
FontSize="19"
TextColor="White"
FontAttributes="Bold"/>
<Label
Margin="0, 2, 0, 0"
Grid.Row="1"
Text="{Binding Description}"
FontSize="16"
TextColor="White"/>
<Label
Margin="0, 10, 0, 0"
Grid.Row="2"
Text="{Binding CreationTime, Converter={converters:TimePrettifyerConverter}}"
FontSize="12"
TextColor="White"/>
</Grid>
</Frame>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
英文:
I have a CollectionView on the homepage. The CollectionView element consists of a Frame as a container and other elements (see the code below). I want to implement changing the color of the Frame when it is selected in collectionView, but VisualStateManager "does not work". And how in this approach can I add Frame animation when I select it?
My ContentPage.Resources code:
<ContentPage.Resources>
<Style TargetType="Frame">
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="Selected">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="Red" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
</ContentPage.Resources>
My CollectionView code:
<CollectionView.ItemTemplate>
<DataTemplate>
<Frame Margin="10, 10, 10, 0"
HeightRequest="100"
MinimumHeightRequest="95"
Padding="13"
CornerRadius="20"
BackgroundColor="DodgerBlue"
BorderColor="Transparent">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Label
Text="{Binding Title}"
FontSize="19"
TextColor="White"
FontAttributes="Bold"/>
<Label
Margin="0, 2, 0, 0"
Grid.Row="1"
Text="{Binding Description}"
FontSize="16"
TextColor="White"/>
<Label
Margin="0, 10, 0, 0"
Grid.Row="2"
Text="{Binding CreationTime, Converter={converters:TimePrettifyerConverter}}"
FontSize="12"
TextColor="White"/>
</Grid>
</Frame>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
答案1
得分: 0
这是我用MVVM方式创建的演示,每次点击按钮都会添加一个新项。
这是我的MainPage.xaml文件(我在底部添加了一个按钮来添加新项):
<StackLayout>
<CollectionView ItemsSource="{Binding ItemCollection}" SelectionMode="Single" HeightRequest="600">
<CollectionView.ItemTemplate>
<DataTemplate>
<Border Margin="10, 10, 10, 0"
HeightRequest="100"
MinimumHeightRequest="95"
Padding="13"
Stroke="Transparent">
<Border.StrokeShape>
<RoundRectangle CornerRadius="20,20,20,20"/>
</Border.StrokeShape>
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Label
Text="{Binding Title}"
FontSize="19"
TextColor="White"
FontAttributes="Bold"/>
<Label
Margin="0, 2, 0, 0"
Grid.Row="1"
Text="{Binding Description}"
FontSize="16"
TextColor="White"/>
<Label
Margin="0, 10, 0, 0"
Grid.Row="2"
Text="{Binding CreationTime}"
FontSize="12"
TextColor="White"/>
</Grid>
</Border>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
<Button Text="click me" Command="{Binding ClickCommand}" />
</StackLayout>
不要忘记在MainPage.cs文件中设置BindingContext:
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
this.BindingContext = new MainPageViewModel();
}
...
这是我的MainPageViewModel,我定义了一个ItemCollection,CollectionView绑定到它。我还为按钮定义了ClickCommand。每次点击按钮,都会向CollectionView添加一个新项。
public class MainPageViewModel
{
public ObservableCollection<Item> ItemCollection { get; set; } = new ObservableCollection<Item>();
// 每次点击按钮,ClickCommand将执行以添加新项
public Command ClickCommand
{
get
{
return new Command(() =>
{
int n = ItemCollection.Count + 1;
ItemCollection.Add(new Item
{
Title = "Title" + n.ToString(),
CreationTime = "CreationTime" + n.ToString()
});
});
}
}
// 在这里只是添加一些测试代码
public MainPageViewModel()
{
ItemCollection.Add(new Item
{
Title = "Title1",
CreationTime = "CreationTime1"
});
// ...
ItemCollection.Add(new Item
{
Title = "Title5",
CreationTime = "CreationTime5"
});
}
}
这是Item.cs,为了方便,我没有使用Converter来处理CreationTime。
public class Item
{
public string Title { get; set; }
public string CreationTime {get;set;}
public Item()
{
}
}
这是我捕获的GIF图像。希望对你有所帮助。
英文:
Update
I made a demo in MVVM way with a new button to add a new Item every time i click the button.
This is my MainPage.xaml file (I add a button at the bottom to add new item):
<StackLayout>
<CollectionView ItemsSource="{Binding ItemCollection}" SelectionMode="Single" HeightRequest="600">
<CollectionView.ItemTemplate>
<DataTemplate>
<Border Margin="10, 10, 10, 0"
HeightRequest="100"
MinimumHeightRequest="95"
Padding="13"
Stroke="Transparent">
<Border.StrokeShape>
<RoundRectangle CornerRadius="20,20,20,20"/>
</Border.StrokeShape>
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Label
Text="{Binding Title}"
FontSize="19"
TextColor="White"
FontAttributes="Bold"/>
<Label
Margin="0, 2, 0, 0"
Grid.Row="1"
Text="{Binding Description}"
FontSize="16"
TextColor="White"/>
<Label
Margin="0, 10, 0, 0"
Grid.Row="2"
Text="{Binding CreationTime}"
FontSize="12"
TextColor="White"/>
</Grid>
</Border>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
<Button Text="click me" Command="{Binding ClickCommand}" />
</StackLayout>
Don't forget to set the BindingContext in MainPage.cs file:
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
this.BindingContext = new MainPageViewModel();
}
...
This is my MainPageViewModel, I define a ItemCollection which CollectionView binds to. I also define the ClickCommand for the button. Each time I click the button, a new item will be added to the CollectionView.
public class MainPageViewModel
{
public ObservableCollection<Item> ItemCollection { get; set; }= new ObservableCollection<Item>();
// each time i clicked the button, ClickCommand will execute to add a new item
public Command ClickCommand
{
get
{
return new Command(() =>
{
int n = ItemCollection.Count + 1;
ItemCollection.Add(new Item
{
Title = "Title" + n.ToString(),
CreationTime = "CreationTime" + n.ToString()
});
});
}
}
//just add some test code here
public MainPageViewModel()
{
ItemCollection.Add(new Item
{
Title = "Title1",
CreationTime = "CreationTime1"
});
......
ItemCollection.Add(new Item
{
Title = "Title5",
CreationTime = "CreationTime5"
});
}
}
This is Item.cs, to for convenience I didn't use Converter for CreationTime.
public class Item
{
public string Title { get; set; }
public string CreationTime {get;set;}
public Item()
{
}
}
Here is the gif I captured:
================== Origin Answer ================
That because you set the Frame BackgroundColor in DataTemplate. So we'd better not set the Property in any other places if we use VisualState in Resources. For a workaround, maybe you could set a normal state (this time we use Border):
<Style TargetType="Border">
......
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" >
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="DodgerBlue" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Selected">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="Red" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
And use Border instead of Frame:
<CollectionView.ItemTemplate>
<DataTemplate>
<Border Margin="10, 10, 10, 0"
HeightRequest="100"
MinimumHeightRequest="95"
Padding="13"
Stroke="Transparent">
<Border.StrokeShape>
<RoundRectangle CornerRadius="20,20,20,20"/>
</Border.StrokeShape>
<Grid>
<Grid.RowDefinitions>
Hope it works for you.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论