如何在运行时编辑 WPF 按钮

How do I edit a WPF button at runtime

所以我使用 Expression Blend 来设计我的按钮。我创建了一个新按钮,通过删除其中的所有内容来编辑按钮的模板。然后我在其中添加了一个网格并将其命名为"grid"。在网格内,我添加了一个文本块并将其命名为 "textBlock"。然后我将模板保存在应用程序下。

这是app.xaml文件中的内容。

<Style x:Key="CustomButtonStyle" TargetType="{x:Type Button}">
        <Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual}"/>
        <Setter Property="Background" Value="{StaticResource Button.Static.Background}"/>
        <Setter Property="BorderBrush" Value="{StaticResource Button.Static.Border}"/>
        <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
        <Setter Property="BorderThickness" Value="1"/>
        <Setter Property="HorizontalContentAlignment" Value="Center"/>
        <Setter Property="VerticalContentAlignment" Value="Center"/>
        <Setter Property="Padding" Value="1"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Button}">
                    <Grid x:Name="grid" HorizontalAlignment="Left" Height="40" VerticalAlignment="Top" Width="90">
                        <TextBlock x:Name="textBlock" HorizontalAlignment="Left" TextWrapping="Wrap" Text="TextBlock" VerticalAlignment="Top" Margin="5,5,0,0" Height="25" Width="75" FontSize="17.333"/>
                    </Grid>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsDefaulted" Value="true"/>
                        <Trigger Property="IsMouseOver" Value="true"/>
                        <Trigger Property="IsPressed" Value="true"/>
                        <Trigger Property="IsEnabled" Value="false"/>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

基本上我打算做的是在运行时创建一个按钮,将此样式应用于按钮,转到按钮的模板,然后更改模板中文本块的文本 属性按钮。

所以对于初学者来说,我没有在运行时创建按钮,而是在编译时创建了一个按钮并将其命名为 "customButton"。然后我尝试编辑按钮模板文本块的文本 属性,但 运行 变为异常。

TextBlock tb = this.customButton.Template.FindName("textBlock", customButton) as TextBlock;
tb.Text = "ASDDDQWEQWEQWE";

请指教谢谢!

创建一个按钮模板,就像您拥有的那样,并为您的每个项目添加控件:

<ControlTemplate TargetType="{x:Type Button}">
                <StackPanel>
                    <Label Content="{Binding CompanyName}" />
                    <Image Source="{Binding Image}" />
                    <Label Content="{Binding StockChange}" />
                </StackPanel>
</ControlTemplate>

或者您可以将其添加到按钮内容中:

<Button>
    <Button.Content>
        <StackPanel>
            <Label Content="{Binding CompanyName}" />
            <Image Source="{Binding Image}" />
            <Label Content="{Binding StockChange}" />
        </StackPanel>
    </Button.Content>
</Button

创建一个 class 来保存来自 API 的数据:

public class CompanyInfo 
{
    public string CompanyName;
    public ImageSource Image;
    public string StockChange;
}

在代码隐藏或视图模型中创建一个 ObservableCollection<CompanyInfo> 来保存根据您的 API 数据创建的 CompanyInfo 对象:

public ObservableCollection<CompanyInfo> CompanyInfoList = new ObservableCollection<CompanyInfo>();

创建一个 ItemsControl 以根据您的数据列表创建按钮:

<ItemsControl ItemsSource="{Binding Path=CompanyInfoList}">

    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>

    <ItemsControl.ItemTemplate>
        <DataTemplate>

            //Button with Bindings Goes Here

        </DataTemplate>
    </ItemsControl.ItemTemplate>

</ItemsControl>

鲍勃是你的叔叔。我建议研究其中的一些内容,以便更好地了解它们的工作原理。

I want to create a button to represent a company stock info like Company name, image, and the % increase in stock price all in one single button. So at runtime, ill get the top 10 stocks from an external API and create 10 buttons at runtime with the information and add it to a stackpanel in my main window.

在这种情况下,您需要使用 ListBox 和 ItemTempate。 试试下面的代码。

 <ListBox x:Name="lstBox">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <Button>
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Text="{Binding CompanyName}" Margin="0,0,10,0"/>
                        <TextBlock Text="{Binding Percent}" />
                    </StackPanel>
                </Button>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        ObservableCollection<CompanyModel> companies = new ObservableCollection<CompanyModel>();
        for (int i = 0; i < 10; i++)
        {
            CompanyModel companyModel = new CompanyModel()
            {
                Percent = i,
                CompanyName = "Name" + i
            };
            companies.Add(companyModel);
        }
        lstBox.ItemsSource = companies;
    }
}

class CompanyModel
    {
        public int Percent { get; set; }
        public string CompanyName { get; set; }
    }