【问题标题】:Fill Stackpanel inside Usercontrol在 Usercontrol 中填充 Stackpanel
【发布时间】:2016-04-01 09:25:09
【问题描述】:

我现在正在搜索几个小时,但找不到正确的方法。

我构建了一个用户控件“MyToolbarGroup”,其中包含一个 GroupText 和一个空的 Stackpanel。

现在我想在我的另一个用户控件“MyUserControl”上使用控件 MyToolbarGroup 并在 MyToolbarGroup 控件的 Stackpanel 中创建一些按钮

MyToolbarGroup-XAML

<UserControl x:Class="TestUi.MyToolbarGroup"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" d:DesignWidth="153" d:DesignHeight="103">
    <Grid>
        <Border BorderBrush="Black" BorderThickness="2">
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="*" />
                    <RowDefinition Height="30" />
                </Grid.RowDefinitions>
                <StackPanel Grid.Row="0" Orientation="Horizontal" HorizontalAlignment="Center" Margin="5,5,5,5" />
                <Label Grid.Row="1" HorizontalContentAlignment="Center" Content="{Binding Path=GroupText}" Background="LightBlue" />
            </Grid>
        </Border>
    </Grid>
</UserControl>

MyToolbarGroup-代码

public partial class MyToolbarGroup : UserControl
{
    public static readonly DependencyProperty GroupTextProperty = DependencyProperty.Register("GroupText", typeof(string), typeof(MyToolbarGroup));

    public String GroupText
    {
        get { return (String)GetValue(GroupTextProperty); }
        set { SetValue(GroupTextProperty, value); }
    }

    public MyToolbarGroup()
    {
        InitializeComponent();
        DataContext = this;
    }
}

MyUserControl-XAML

<UserControl
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:TestUi" x:Class="TestUi.MyUserControl" 
             mc:Ignorable="d" 
             d:DesignHeight="224" d:DesignWidth="343">
    <Grid>
        <local:MyToolbarGroup HorizontalAlignment="Left" Margin="40,30,0,0" VerticalAlignment="Top" Height="148" Width="238" GroupText="Test-Group">
            <!-- Something like that
            <Stackpanel-Inside-MyToolbarGroup>
                <Button  HorizontalAlignment="Center" VerticalAlignment="Center" Height="65" Width="65" Content="Button 1"/>
            </Stackpanel-Inside-MyToolbarGroup>
            -->
        </local:MyToolbarGroup>
    </Grid>
</UserControl>

任何想法如何在堆栈面板中设置一些按钮?

感谢您的帮助!

【问题讨论】:

  • 创建按钮并不难,但是你想用这些按钮做什么呢?你想让他们执行一些命令吗?
  • 是的,这些按钮将用于执行命令。但是,稍后还应该有标签或其他 UI 控件。但主要是按钮。

标签: c# wpf xaml user-controls


【解决方案1】:

在 MyToolbarGroup 模板中包含一个 ContentPresenter 以接受用户内容

<UserControl x:Class="TestUi.MyToolbarGroup"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:testUi="clr-namespace:TestUi"
             mc:Ignorable="d" d:DesignWidth="153" d:DesignHeight="103">
    <UserControl.Template>
        <ControlTemplate TargetType="UserControl">
            <Grid>
                <Border BorderBrush="Black" BorderThickness="2">
                    <Grid>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="*" />
                            <RowDefinition Height="30" />
                        </Grid.RowDefinitions>

                        <ContentPresenter Content="{TemplateBinding Content}"/>

                        <Label Grid.Row="1" HorizontalContentAlignment="Center"
                               Content="{Binding GroupText, RelativeSource={RelativeSource AncestorType=testUi:MyToolbarGroup}}"
                               Background="LightBlue" />
                    </Grid>
                </Border>
            </Grid>
        </ControlTemplate>
    </UserControl.Template>
</UserControl>

然后像这样使用它:

<testUi:MyToolbarGroup Grid.Row="2"
    HorizontalAlignment="Left" 
    VerticalAlignment="Top" 
    Height="148" Width="238" GroupText="Test-Group">
    <!--any content, e.g. -->
    <StackPanel Orientation="Horizontal">
        <TextBlock Text="A" Margin="5"/>
        <TextBlock Text="B"  Margin="5"/>
    </StackPanel>
</testUi:MyToolbarGroup>

结果:

【讨论】:

  • 是的,这是正确的选择。你想定义你的UserControl.Template,而不是UserControl.ContentUserControl.Content 会在您尝试使用其他内容时被覆盖,但UserControl.Template 定义的是如何包装给控件的.Content
【解决方案2】:

堆栈面板没有您想要的功能(如果我理解正确的话)。您想要的是基于某些数据的动态控件集合吗?

你需要的是一个 ItemsControl:

<ItemsControl ItemsSource="{Binding MyButtonDataCollection}"  >
    <ItemsControl.ItemTemplate >
        <DataTemplate >
            <Button Content="{Binding ButtonName}"
                    Command="{Binding ButtonClick}"
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

绑定到具有您要绑定的属性和命令的数据对象集合:

class MyButtonData : INotifyPropertyChanged
{
    String ButtonName { get; set; } //notify property changed and all that

    public ICommand ButtonClick
    {
        get;
        internal set;
    }

    private bool CanExecuteButtonClick()
    {
        //can this execute?
        return true;
    }

    private void CreateButtonClick()
    {
        ButtonClick = new RelayCommand(SaveExecute, CanExecuteSaveCommand);
    }

    public void ButtonClickExecute()
    {
        //do my logic for click
    }
}

【讨论】:

    【解决方案3】:

    如果您想要预定义MyToolbarGroup 内部的布局,您需要将StackPanel 替换为ItemsControl,将StackPanel 替换为ItemsPanel

    这里是MyToolbarGroup XAML:

    <UserControl x:Class="WpfApplication2.MyToolbarGroup"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:local="clr-namespace:WpfApplication2">
        <Border BorderBrush="Black" BorderThickness="2">
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="*" />
                    <RowDefinition Height="30" />
                </Grid.RowDefinitions>
                <ItemsControl Grid.Row="0" HorizontalAlignment="Center" Margin="5,5,5,5"
                              ItemsSource="{Binding GroupItems, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}}">
                    <ItemsControl.ItemsPanel>
                        <ItemsPanelTemplate>
                            <StackPanel Orientation="Horizontal" />
                        </ItemsPanelTemplate>
                    </ItemsControl.ItemsPanel>
                </ItemsControl>
    
                <Label Grid.Row="1" HorizontalContentAlignment="Center"
                       Content="{Binding GroupText, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}}"
                       Background="LightBlue" />
            </Grid>
        </Border>
    </UserControl>
    

    和代码隐藏:

    public partial class MyToolbarGroup : UserControl
    {
        public MyToolbarGroup()
        {
            InitializeComponent();
        }
    
        public string GroupText
        {
            get { return (string)GetValue(GroupTextProperty); }
            set { SetValue(GroupTextProperty, value); }
        }
    
        public static readonly DependencyProperty GroupTextProperty =
            DependencyProperty.Register("GroupText", typeof(string), typeof(MyToolbarGroup), new PropertyMetadata(null));
    
        public IEnumerable GroupItems
        {
            get { return (IEnumerable)GetValue(GroupItemsProperty); }
            set { SetValue(GroupItemsProperty, value); }
        }
    
        public static readonly DependencyProperty GroupItemsProperty =
            DependencyProperty.Register("GroupItems", typeof(IEnumerable), typeof(MyToolbarGroup), new PropertyMetadata(null));
    }
    

    现在,您可以像这样使用它:

    <Window x:Class="WpfApplication2.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:sys="clr-namespace:System;assembly=mscorlib"
            xmlns:local="clr-namespace:WpfApplication2"
            Title="MainWindow">
        <Grid>
            <local:MyToolbarGroup HorizontalAlignment="Left" Margin="40,30,0,0" VerticalAlignment="Top" Height="148" Width="238" GroupText="Test-Group">
                <local:MyToolbarGroup.GroupItems>
                    <x:Array Type="{x:Type sys:Object}">
                        <Button HorizontalAlignment="Center" VerticalAlignment="Center" Height="65" Width="65" Content="Button 1"/>
                        <Button HorizontalAlignment="Center" VerticalAlignment="Center" Height="65" Width="65" Content="Button 2"/>
                        <Button HorizontalAlignment="Center" VerticalAlignment="Center" Height="65" Width="65" Content="Button 3"/>
                    </x:Array>
                </local:MyToolbarGroup.GroupItems>
            </local:MyToolbarGroup>
        </Grid>
    </Window>
    

    结果截图:

    【讨论】:

      猜你喜欢
      • 2013-02-26
      • 2010-11-21
      • 1970-01-01
      • 1970-01-01
      • 2021-12-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多