在 C#/UWP 中自定义时间选择器
Customizing the Time-Picker in C#/UWP
好吧,我到处都找遍了,似乎找不到回答过这个问题的人。我想自定义 UWP 中的时间选择器控件,自定义是指我不希望它成为一个时钟。
我需要一个允许用户滚动循环菜单的 GUI,就像时间选择器一样,但我想不出一种方法来更改时间选择器控件,以便它显示除 Hour/Minute/AM-PM。我还尝试使用带有旋转木马面板和其中项目的组合框,但它没有呈现我正在寻找的效果。如果有人可以,我将不胜感激 A.) 告诉我是否可以更改时间选择器,或 B.) 将我指向一个控件的方向,该控件将呈现我正在寻找的 scrolling/looping 效果为了。我不需要任何人为我做我的工作,只需要朝着正确的方向稍微推动一下。
明确地说,我希望菜单具有与 Windows 闹钟 Setter 相同的效果,如果这有助于视觉。
您可以创建一个基本的手工控件,例如有 4 个列表视图。
这里有一个简单的例子:
<Button Content="Set localisation" HorizontalAlignment="Center" VerticalAlignment="Center">
<Button.Flyout>
<Flyout Opened="Flyout_Opened">
<StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Center">
<Grid MaxHeight="150" MinWidth="100">
<ListView ItemsSource="{x:Bind Degrees,Mode=OneWay}" SelectedIndex="{x:Bind SelectedDegrees,Mode=TwoWay}" >
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsStackPanel ItemsUpdatingScrollMode="KeepItemsInView" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
<Grid MaxHeight="150" MinWidth="100">
<ListView ItemsSource="{x:Bind Minutes,Mode=OneWay}" SelectedIndex="{x:Bind SelectedMinutes,Mode=TwoWay}">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsStackPanel ItemsUpdatingScrollMode="KeepItemsInView" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
<Grid MaxHeight="150" MinWidth="100">
<ListView ItemsSource="{x:Bind Seconds,Mode=OneWay}" SelectedIndex="{x:Bind SelectedSeconds,Mode=TwoWay}">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsStackPanel ItemsUpdatingScrollMode="KeepItemsInView" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
<Grid MaxHeight="150" MinWidth="100">
<ListView ItemsSource="{x:Bind Hundredth,Mode=OneWay}" SelectedIndex="{x:Bind SelectedHundredth,Mode=TwoWay}">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsStackPanel ItemsUpdatingScrollMode="KeepItemsInView" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</StackPanel>
</Flyout>
</Button.Flyout>
</Button>
使用此 C# 代码:
public ObservableCollection<int> Degrees = new ObservableCollection<int>
{
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30
};
private int selectedDegrees = 0;
public int SelectedDegrees
{
get { return selectedDegrees; }
set { selectedDegrees = value; PropertyChanged?.Invoke(this, new ProportyChangedEventArgs(nameof(SelectedDegrees))); }
}
public ObservableCollection<int> Minutes = new ObservableCollection<int>
{
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30
};
private int selectedMinutes = 0;
public int SelectedMinutes
{
get { return selectedMinutes; }
set { selectedMinutes = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SelectedMinutes))); }
}
public ObservableCollection<int> Seconds = new ObservableCollection<int>
{
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30
};
private int selectedSeconds = 0;
public int SelectedSeconds
{
get { return selectedSeconds; }
set { selectedSeconds = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SelectedSeconds))); }
}
public ObservableCollection<int> Hundredth = new ObservableCollection<int>
{
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30
};
private int selectedHundredth = 0;
public int SelectedHundredth
{
get { return selectedHundredth; }
set { selectedHundredth = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SelectedHundredth))); }
}
private async void Flyout_Opened(object sender, object e)
{
await Task.Delay(100);
SelectedDegrees = 5;
SelectedMinutes = 4;
SelectedSeconds = 3;
SelectedHundredth = 1;
}
这是它的外观:
轮播
在编写这些行时,列表视图中没有任何 looping/carousel。但是 Combobox 中有一个,我建议使用组合框而不是 ListView 控件。
<ComboBox ItemsSource="{x:Bind Degrees,Mode=OneWay}" SelectedIndex="{x:Bind SelectedDegrees,Mode=TwoWay}" IsDropDownOpen="True">
<ComboBox.ItemsPanel>
<ItemsPanelTemplate>
<CarouselPanel />
</ItemsPanelTemplate>
</ComboBox.ItemsPanel>
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
好吧,我到处都找遍了,似乎找不到回答过这个问题的人。我想自定义 UWP 中的时间选择器控件,自定义是指我不希望它成为一个时钟。
我需要一个允许用户滚动循环菜单的 GUI,就像时间选择器一样,但我想不出一种方法来更改时间选择器控件,以便它显示除 Hour/Minute/AM-PM。我还尝试使用带有旋转木马面板和其中项目的组合框,但它没有呈现我正在寻找的效果。如果有人可以,我将不胜感激 A.) 告诉我是否可以更改时间选择器,或 B.) 将我指向一个控件的方向,该控件将呈现我正在寻找的 scrolling/looping 效果为了。我不需要任何人为我做我的工作,只需要朝着正确的方向稍微推动一下。
明确地说,我希望菜单具有与 Windows 闹钟 Setter 相同的效果,如果这有助于视觉。
您可以创建一个基本的手工控件,例如有 4 个列表视图。 这里有一个简单的例子:
<Button Content="Set localisation" HorizontalAlignment="Center" VerticalAlignment="Center">
<Button.Flyout>
<Flyout Opened="Flyout_Opened">
<StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Center">
<Grid MaxHeight="150" MinWidth="100">
<ListView ItemsSource="{x:Bind Degrees,Mode=OneWay}" SelectedIndex="{x:Bind SelectedDegrees,Mode=TwoWay}" >
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsStackPanel ItemsUpdatingScrollMode="KeepItemsInView" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
<Grid MaxHeight="150" MinWidth="100">
<ListView ItemsSource="{x:Bind Minutes,Mode=OneWay}" SelectedIndex="{x:Bind SelectedMinutes,Mode=TwoWay}">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsStackPanel ItemsUpdatingScrollMode="KeepItemsInView" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
<Grid MaxHeight="150" MinWidth="100">
<ListView ItemsSource="{x:Bind Seconds,Mode=OneWay}" SelectedIndex="{x:Bind SelectedSeconds,Mode=TwoWay}">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsStackPanel ItemsUpdatingScrollMode="KeepItemsInView" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
<Grid MaxHeight="150" MinWidth="100">
<ListView ItemsSource="{x:Bind Hundredth,Mode=OneWay}" SelectedIndex="{x:Bind SelectedHundredth,Mode=TwoWay}">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsStackPanel ItemsUpdatingScrollMode="KeepItemsInView" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</StackPanel>
</Flyout>
</Button.Flyout>
</Button>
使用此 C# 代码:
public ObservableCollection<int> Degrees = new ObservableCollection<int>
{
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30
};
private int selectedDegrees = 0;
public int SelectedDegrees
{
get { return selectedDegrees; }
set { selectedDegrees = value; PropertyChanged?.Invoke(this, new ProportyChangedEventArgs(nameof(SelectedDegrees))); }
}
public ObservableCollection<int> Minutes = new ObservableCollection<int>
{
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30
};
private int selectedMinutes = 0;
public int SelectedMinutes
{
get { return selectedMinutes; }
set { selectedMinutes = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SelectedMinutes))); }
}
public ObservableCollection<int> Seconds = new ObservableCollection<int>
{
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30
};
private int selectedSeconds = 0;
public int SelectedSeconds
{
get { return selectedSeconds; }
set { selectedSeconds = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SelectedSeconds))); }
}
public ObservableCollection<int> Hundredth = new ObservableCollection<int>
{
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30
};
private int selectedHundredth = 0;
public int SelectedHundredth
{
get { return selectedHundredth; }
set { selectedHundredth = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SelectedHundredth))); }
}
private async void Flyout_Opened(object sender, object e)
{
await Task.Delay(100);
SelectedDegrees = 5;
SelectedMinutes = 4;
SelectedSeconds = 3;
SelectedHundredth = 1;
}
这是它的外观:
轮播
在编写这些行时,列表视图中没有任何 looping/carousel。但是 Combobox 中有一个,我建议使用组合框而不是 ListView 控件。
<ComboBox ItemsSource="{x:Bind Degrees,Mode=OneWay}" SelectedIndex="{x:Bind SelectedDegrees,Mode=TwoWay}" IsDropDownOpen="True">
<ComboBox.ItemsPanel>
<ItemsPanelTemplate>
<CarouselPanel />
</ItemsPanelTemplate>
</ComboBox.ItemsPanel>
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>