使用 material 设计 WPF 动态添加控件
Add control dynamically using material design WPF
我是 WPF 新手。我想使用 Material 设计的桌面应用程序之一。我添加了 MaterialDesign nuget 包并成功实施。
在这种情况下,我需要在单击按钮时添加按钮或卡片。那些是完全动态的。
我可以从 C# 动态添加 material 设计控件吗?
帮我举个例子。
提前致谢
我相信您可能正在使用 Material Design In XAML. Make sure to check out the demo project。包含常见控件用法的所有答案。
选项一。
您通常会使用 "ItemsControl" 将对象动态加载到视图中。项目控件链接到后端视图模型中的项目源。源应该是 ObservableCollection 类型。当您向此源提供项目时,ItemsControl 将根据它提供的模板进行更新和插入。
下面是一个基本的简短示例。
xaml
<ItemsControl ItemsSource="{Binding ItemsToLoad}" Grid.IsSharedSizeScope="True" Margin="12 0 12 0">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button>Hi</Button>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
我假设您对绑定有很好的理解,所以我不会发布所有后端代码。
选项二
以编程方式
看到你提到你想以编程方式进行,你也可以这样做:
第 1 步:创建网格并设置供您使用的布局。
<Grid x:Name="grid_Main">
<Grid.ColumnsDefinition>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnsDefinition>
<Grid.RowDefinition>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinition>
</Grid>
第 2 步:代码隐藏。
private void AddControlToGrid()
{
Button button = new Button();
grid_Main.Children.Add(button );
Grid.SetRow(button , 1); // 1 is row index
Grid.SetColumn(button , 0);// 0 is column index
}
只是 material 设计用法的注释。您需要先引用该库,然后才能在您的视图中使用它。
像这样:
将此添加到您的应用程序资源中。
<Application x:Class="demo_app.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:demo_app">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Light.xaml" />
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Defaults.xaml" />
<ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Primary/MaterialDesignColor.DeepPurple.xaml" />
<ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Accent/MaterialDesignColor.Lime.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
将此引用添加到您需要使用 material 设计控件的任何视图。
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
然后您可以像这样使用 material 设计控件。
<materialDesign:Card Width="200">
<Grid>
<!--Content-->
</Grid>
</materialDesign:Card>
我参考了以下 link 的 material 设计解决方案。
How to generate WPF controls automatically based on XML file?
我不知道这种方式在 material 设计中是否有效,但我成功地获得了卡片控制的结果。
StackPanel stackPanel = new StackPanel();
MaterialDesignThemes.Wpf.Card card = new MaterialDesignThemes.Wpf.Card();
StringBuilder sb = new StringBuilder();
//Create card
sb.Append(@"<materialDesign:Card xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation' xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml' xmlns:materialDesign='http://materialdesigninxaml.net/winfx/xaml/themes' Background='#03a9f4' Foreground = '{DynamicResource PrimaryHueDarkForegroundBrush}' Padding = '0' Width = '200'> ");
sb.Append(@"<Grid><Grid.RowDefinitions><RowDefinition Height='Auto' /><RowDefinition Height = 'Auto' /><RowDefinition Height = 'Auto' /></Grid.RowDefinitions> ");
sb.Append(@"<TextBlock Grid.Row='0' Margin = '16 16 16 4' Style = '{StaticResource MaterialDesignHeadlineTextBlock}'> Call Jennifer </TextBlock><Separator Grid.Row = '1' Style = '{StaticResource MaterialDesignLightSeparator}' /><TextBlock Grid.Row = '2' Margin = '16 0 16 8' VerticalAlignment = 'Center' HorizontalAlignment = 'Left' Style = '{StaticResource MaterialDesignBody2TextBlock}'> March 19, 2016 </TextBlock>");
sb.Append(@"</Grid></materialDesign:Card>");
card = (MaterialDesignThemes.Wpf.Card)XamlReader.Parse(sb.ToString());
// Add created button to previously created container.
stackPanel.Children.Add(card);
this.Content = stackPanel;
如果我们仔细观察,
xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation' xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml' xmlns:materialDesign='http://materialdesigninxaml.net/winfx/xaml/themes'
准备新的动态控件时,以上属性无能为力。
我从上面的代码得到的结果Dynamic Material design control
您可以简单地这样做:
Card card = new Card();
StackPanel stackPanel = new StackPanel { Orientation = Orientation.Vertical };
stackPanel.Children.Add(new Label { Content = "Test"});
card.Content = stackPanel;
我是这样做的。下面的 Xaml 改编自 Material Design In XAML nuget package GitHub 示例。
"smtx:XamlDisplay" 来自 "ShowMeTheXaml",也用于 GitHub 演示 (https://github.com/MaterialDesignInXAML/MaterialDesignInXamlToolkit/blob/master/MainDemo.Wpf/Progress.xaml)
<smtx:XamlDisplay x:Name="prgDisplay" Key="progress" Grid.Row="2" VerticalAlignment="Center" HorizontalAlignment="Center" Margin="12" Visibility="Hidden">
<materialDesign:Card UniformCornerRadius="99" Padding="4" Opacity="0.95" Background="{StaticResource BrushPrimaryLight}">
<ProgressBar Style="{StaticResource MaterialDesignCircularProgressBar}"
Value="50" IsIndeterminate="True"
Foreground="{StaticResource BrushPrimaryDark}"
Height="100" Width="100"/>
</materialDesign:Card>
</smtx:XamlDisplay>
如果您使用的是 MVVM,则在后面的代码或其他地方。
private void ToggleProgressBarVisibility()
{
if (prgDisplay.Visibility == Visibility.Visible)
prgDisplay.Visibility = Visibility.Hidden;
else
prgDisplay.Visibility = Visibility.Visible;
}
我是 WPF 新手。我想使用 Material 设计的桌面应用程序之一。我添加了 MaterialDesign nuget 包并成功实施。 在这种情况下,我需要在单击按钮时添加按钮或卡片。那些是完全动态的。 我可以从 C# 动态添加 material 设计控件吗? 帮我举个例子。
提前致谢
我相信您可能正在使用 Material Design In XAML. Make sure to check out the demo project。包含常见控件用法的所有答案。
选项一。
您通常会使用 "ItemsControl" 将对象动态加载到视图中。项目控件链接到后端视图模型中的项目源。源应该是 ObservableCollection 类型。当您向此源提供项目时,ItemsControl 将根据它提供的模板进行更新和插入。
下面是一个基本的简短示例。
xaml
<ItemsControl ItemsSource="{Binding ItemsToLoad}" Grid.IsSharedSizeScope="True" Margin="12 0 12 0">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button>Hi</Button>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
我假设您对绑定有很好的理解,所以我不会发布所有后端代码。
选项二
以编程方式
看到你提到你想以编程方式进行,你也可以这样做:
第 1 步:创建网格并设置供您使用的布局。
<Grid x:Name="grid_Main">
<Grid.ColumnsDefinition>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnsDefinition>
<Grid.RowDefinition>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinition>
</Grid>
第 2 步:代码隐藏。
private void AddControlToGrid()
{
Button button = new Button();
grid_Main.Children.Add(button );
Grid.SetRow(button , 1); // 1 is row index
Grid.SetColumn(button , 0);// 0 is column index
}
只是 material 设计用法的注释。您需要先引用该库,然后才能在您的视图中使用它。
像这样:
将此添加到您的应用程序资源中。
<Application x:Class="demo_app.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:demo_app">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Light.xaml" />
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Defaults.xaml" />
<ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Primary/MaterialDesignColor.DeepPurple.xaml" />
<ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Accent/MaterialDesignColor.Lime.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
将此引用添加到您需要使用 material 设计控件的任何视图。
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
然后您可以像这样使用 material 设计控件。
<materialDesign:Card Width="200">
<Grid>
<!--Content-->
</Grid>
</materialDesign:Card>
我参考了以下 link 的 material 设计解决方案。 How to generate WPF controls automatically based on XML file? 我不知道这种方式在 material 设计中是否有效,但我成功地获得了卡片控制的结果。
StackPanel stackPanel = new StackPanel();
MaterialDesignThemes.Wpf.Card card = new MaterialDesignThemes.Wpf.Card();
StringBuilder sb = new StringBuilder();
//Create card
sb.Append(@"<materialDesign:Card xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation' xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml' xmlns:materialDesign='http://materialdesigninxaml.net/winfx/xaml/themes' Background='#03a9f4' Foreground = '{DynamicResource PrimaryHueDarkForegroundBrush}' Padding = '0' Width = '200'> ");
sb.Append(@"<Grid><Grid.RowDefinitions><RowDefinition Height='Auto' /><RowDefinition Height = 'Auto' /><RowDefinition Height = 'Auto' /></Grid.RowDefinitions> ");
sb.Append(@"<TextBlock Grid.Row='0' Margin = '16 16 16 4' Style = '{StaticResource MaterialDesignHeadlineTextBlock}'> Call Jennifer </TextBlock><Separator Grid.Row = '1' Style = '{StaticResource MaterialDesignLightSeparator}' /><TextBlock Grid.Row = '2' Margin = '16 0 16 8' VerticalAlignment = 'Center' HorizontalAlignment = 'Left' Style = '{StaticResource MaterialDesignBody2TextBlock}'> March 19, 2016 </TextBlock>");
sb.Append(@"</Grid></materialDesign:Card>");
card = (MaterialDesignThemes.Wpf.Card)XamlReader.Parse(sb.ToString());
// Add created button to previously created container.
stackPanel.Children.Add(card);
this.Content = stackPanel;
如果我们仔细观察, xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation' xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml' xmlns:materialDesign='http://materialdesigninxaml.net/winfx/xaml/themes' 准备新的动态控件时,以上属性无能为力。
我从上面的代码得到的结果Dynamic Material design control
您可以简单地这样做:
Card card = new Card();
StackPanel stackPanel = new StackPanel { Orientation = Orientation.Vertical };
stackPanel.Children.Add(new Label { Content = "Test"});
card.Content = stackPanel;
我是这样做的。下面的 Xaml 改编自 Material Design In XAML nuget package GitHub 示例。
"smtx:XamlDisplay" 来自 "ShowMeTheXaml",也用于 GitHub 演示 (https://github.com/MaterialDesignInXAML/MaterialDesignInXamlToolkit/blob/master/MainDemo.Wpf/Progress.xaml)
<smtx:XamlDisplay x:Name="prgDisplay" Key="progress" Grid.Row="2" VerticalAlignment="Center" HorizontalAlignment="Center" Margin="12" Visibility="Hidden">
<materialDesign:Card UniformCornerRadius="99" Padding="4" Opacity="0.95" Background="{StaticResource BrushPrimaryLight}">
<ProgressBar Style="{StaticResource MaterialDesignCircularProgressBar}"
Value="50" IsIndeterminate="True"
Foreground="{StaticResource BrushPrimaryDark}"
Height="100" Width="100"/>
</materialDesign:Card>
</smtx:XamlDisplay>
如果您使用的是 MVVM,则在后面的代码或其他地方。
private void ToggleProgressBarVisibility()
{
if (prgDisplay.Visibility == Visibility.Visible)
prgDisplay.Visibility = Visibility.Hidden;
else
prgDisplay.Visibility = Visibility.Visible;
}