gpt4 book ai didi

c# - 如何创建可重用的 UserControl 并将命令绑​​定到它?

转载 作者:太空宇宙 更新时间:2023-11-03 21:00:27 24 4
gpt4 key购买 nike

我正在尝试在 carusel 中绑定(bind)一个可重复使用的按钮,我想要实现的是添加假设 6 个按钮,每个按钮将有一个命令,根据按钮名称将导航到正确的页面。

我可以这样做:

<toolkitcontrols:Carousel x:Name="NavigationMenuCarouselPanel"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Orientation="Horizontal"
ItemsSource="{x:Bind ViewModel.MenuList, Mode=OneWay}"
ItemMargin="25"
ItemDepth="160"
ItemRotationX="180"
ItemRotationY="25"
ItemRotationZ="0"
SelectedIndex="2"
Grid.Row="1">
<toolkitcontrols:Carousel.EasingFunction>
<CubicEase EasingMode="EaseOut"/>
</toolkitcontrols:Carousel.EasingFunction>
<Button Command="{x:Bind ViewModel.NavigateToPage1, Mode=OneWay}"
Content="{x:Bind ViewModel.Name, Mode=OneWay}"/>
</toolkitcontrols:Carousel>

如果这样做,我将再添加 5 个按钮,并且我必须为每个按钮编写属性。

所以我想使用 UserControl 并编写如下内容:

<toolkitcontrols:Carousel x:Name="NavigationMenuCarouselPanel"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Orientation="Horizontal"
ItemsSource="{x:Bind ViewModel.MenuList, Mode=OneWay}"
ItemMargin="25"
ItemDepth="160"
ItemRotationX="180"
ItemRotationY="25"
ItemRotationZ="0"
SelectedIndex="2"
Grid.Row="1">
<toolkitcontrols:Carousel.EasingFunction>
<CubicEase EasingMode="EaseOut"/>
</toolkitcontrols:Carousel.EasingFunction>
<toolkitcontrols:Carousel.ItemTemplate>
<DataTemplate x:DataType="data:ButtonInfo">
<usercontrolvm:NavigationMenuButtonTemplate NavigateToPageCommand="{Binding NavigateToPageCommand}"/>
</DataTemplate>
</toolkitcontrols:Carousel.ItemTemplate>
</toolkitcontrols:Carousel>

但我没有这样做,我找到了一些教程,但据我所知,所有这些都会让我写出这样的代码:

<usercontrolvm:NavigationMenuButtonTemplate NavigateToPageCommand="{Binding NavigateToPageCommand}"/>

大约 6 次,我不知道如何将 DataTemplate 的 x:DataType 用于我的属性列表。

这是我的 UserControl.xaml.cs

public sealed partial class NavigationMenuButtonTemplate : UserControl
{
public ButtonInfo ButtonInfo => (DataContext as ButtonInfo);

public NavigationMenuButtonTemplate()
{
this.InitializeComponent();
Loaded += NavigationMenuButtonTemplate_Loaded;
}

private void NavigationMenuButtonTemplate_Loaded(object sender, RoutedEventArgs e)
{
Bindings.Update();
}

public DelegateCommand NavigateToPageCommand
{
get { return (DelegateCommand)GetValue(NavigateToPageCommandProperty); }
set { SetValue(NavigateToPageCommandProperty, value); }
}

// Using a DependencyProperty as the backing store for NavigateToPageCommand. This enables animation, styling, binding, etc...
public static readonly DependencyProperty NavigateToPageCommandProperty =
DependencyProperty.Register("NavigateToPageCommand",
typeof(DelegateCommand),
typeof(NavigationMenuButtonTemplate),
new PropertyMetadata(0));
}

这是我的 ButtonInfo.cs

public class ButtonInfo
{
public string Symbol { get; set; }
public string FontFamily { get; set; }
public string MenuName { get; set; }
public string BenefitKind { get; set; }
public string Status { get; set; }
}

这是我的 UserControl.xaml

<Button x:Name="NavigationMenuTemplate"
Width="300"
Height="300"
Command="{Binding NavigateToPageCommand, ElementName=root, Mode=OneWay}">
<Grid x:Name="ButtonLayout">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock x:Name="NavigationMenuIconTextBlock"
Grid.Row="0"
Grid.Column="0"
Grid.ColumnSpan="2"
FontFamily="{x:Bind ButtonInfo.FontFamily, Mode=OneWay, FallbackValue='Webdings'}"
Text="{x:Bind ButtonInfo.Symbol, Mode=OneWay, FallbackValue='&#x91;'}"
FontSize="150"
Foreground="Black"
VerticalAlignment="Center"
HorizontalAlignment="Center"/>
<TextBlock x:Name="NavigationMenuButtonNameTextBlock"
Grid.Row="1"
Grid.Column="0"
Grid.ColumnSpan="2"
Text="{x:Bind ButtonInfo.MenuName, Mode=OneWay, FallbackValue='CALCULADORA JORNADAS EXTRAORDINARIAS'}"
FontSize="12"
Foreground="Black"
HorizontalAlignment="Center"/>
<TextBlock x:Name="NavigationMenuButtonBenefitKindTextBlock"
Grid.Row="2"
Grid.Column="0"
Text="{x:Bind ButtonInfo.BenefitKind, Mode=OneWay, FallbackValue='Subscripción'}"
FontSize="10"
Foreground="Black"
HorizontalAlignment="Left"/>
<TextBlock x:Name="NavigationMenuButtonStatusTextBlock"
Grid.Row="2"
Grid.Column="1"
Text="{x:Bind ButtonInfo.Status, Mode=OneWay, FallbackValue='Vigente'}"
FontSize="10"
Foreground="Black"
HorizontalAlignment="Right"/>
</Grid>
</Button>

请有人帮助我并指出正确的方向。我错过了什么?

最佳答案

ItemTemplate您问题中的方法实际上是在正确的轨道上。

最后,您的 XAML 将类似于以下内容(仅包含一些属性,但您明白了)-

<toolkitcontrols:Carousel ItemsSource="{x:Bind ButtonInfoCollection}">
<toolkitcontrols:Carousel.ItemTemplate>
<DataTemplate x:DataType="local:ButtonInfo">
<local:NavigationMenuButton NavigateToPageCommand="{Binding DataContext.NavigateToPageCommand, ElementName=MyPageName}"
NavigateToPageCommandParameter="{x:Bind PageType}"
MenuName="{x:Bind MenuName}"
SymbolPath="{x:Bind Symbol}" />
</DataTemplate>
</toolkitcontrols:Carousel.ItemTemplate>
</toolkitcontrols:Carousel>

考虑到上述结构,您只需要在 NavigationMenuButton 中将这些属性公开为依赖属性用户控制。请参阅下面的简单示例 -

NavigationMenuButton XAML

<UserControl x:Class="DesignTest.NavigationMenuButton">

<!--If any of the properties can be updated, change the binding Mode to OneWay-->
<Button Command="{x:Bind NavigateToPageCommand, Mode=OneWay}" CommandParameter="{x:Bind NavigateToPageCommandParameter}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20" />
<ColumnDefinition />
</Grid.ColumnDefinitions>

<Image x:Name="SymbolImage" Stretch="UniformToFill" />
<TextBlock Text="{x:Bind MenuName, FallbackValue='JORNADAS EXTRAORDINARIAS', TargetNullValue='JORNADAS EXTRAORDINARIAS'}" Grid.Column="1" />
</Grid>
</Button>
</UserControl>

NavigationMenuButton 代码隐藏

public sealed partial class NavigationMenuButton : UserControl
{
public NavigationMenuButton()
{
InitializeComponent();
}

public ICommand NavigateToPageCommand
{
get => (ICommand)GetValue(NavigateToPageCommandProperty);
set => SetValue(NavigateToPageCommandProperty, value);
}
public static readonly DependencyProperty NavigateToPageCommandProperty = DependencyProperty.Register(
"NavigateToPageCommand", typeof(ICommand), typeof(NavigationMenuButton), new PropertyMetadata(null));

public object NavigateToPageCommandParameter
{
get => GetValue(NavigateToPageCommandParameterProperty);
set => SetValue(NavigateToPageCommandParameterProperty, value);
}
public static readonly DependencyProperty NavigateToPageCommandParameterProperty = DependencyProperty.Register(
"NavigateToPageCommandParameter", typeof(object), typeof(NavigationMenuButton), new PropertyMetadata(null));

public string MenuName
{
get => (string)GetValue(MenuNameProperty);
set => SetValue(MenuNameProperty, value);
}
public static readonly DependencyProperty MenuNameProperty = DependencyProperty.Register(
"MenuName", typeof(string), typeof(NavigationMenuButton), new PropertyMetadata(null));

public string SymbolPath
{
get => (string)GetValue(SymbolPathProperty);
set => SetValue(SymbolPathProperty, value);
}
public static readonly DependencyProperty SymbolPathProperty = DependencyProperty.Register(
"SymbolPath", typeof(string), typeof(NavigationMenuButton), new PropertyMetadata(null, (s, e) =>
{
// We don't do the x:Bind for this property in XAML because the Image control's Source property
// doesn't accept a string but a BitmapImage, so one workaround is to do the conversion here.

var self = (NavigationMenuButton)s;
var image = self.SymbolImage;
var symbolPath = (string)e.NewValue;

image.Source = new BitmapImage(new Uri(self.BaseUri, symbolPath ?? "/Assets/default_path"));
}));
}

请注意,您需要包含 PageType您的属性(property) ButtonInfo用于导航目的的类。

public Type PageType { get; set; }

我个人不喜欢在项目级别定义导航命令(即在 ButtonInfo 类中),相反,我使用 ElementNameCarousel 中绑定(bind)的数据模板以向上搜索一个级别并绑定(bind)到 NavigateToPageCommand在页面的 DataContext 中定义,这是页面的 ViewModel .

这意味着这个 ViewModel将同时拥有 ButtonInfoCollectionNavigateToPageCommand定义如下 -

public ObservableCollection<ButtonInfo> ButtonInfoCollection { get; } = new ObservableCollection<ButtonInfo>
{
new ButtonInfo { MenuName = "New Menu", PageType = typeof(BlankPage1), Symbol = "/Assets/StoreLogo.png" }
};

public DelegateCommand<Type> NavigateToPageCommand { get; } = new DelegateCommand<Type>(type =>
App.Frame.Navigate(type));

我希望这一切都有意义。祝你好运!

关于c# - 如何创建可重用的 UserControl 并将命令绑​​定到它?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46031043/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com