WPF Control Manipulation
I need to dynamically add the controls to a window. For example for a comboBox, I need to map with the Custom Framework which will map the Lookup to that comboBox...
So whenever the combobox is mapped with lookup, I need to Add a (+) Button to the right side of the comboBox.. This (+) button is used to open a respective lookup form to add an item to the comboBox.
For that I need to do the following..
- In Mapper I need to create instance for Button Label with (+),
- I need to create a Panel., ie., Container for holding both the Controls (ComboBox,Button)
- For replacing Combobox with that created panel, I need to remove the Combobox from the Paren开发者_如何学Pythont of Combobox and add panel to that control.
How can we do this in WPF? ie. dynamically replacing controls in Code behind.
Thanks in advance, Dinesh
I would suggest using MVVM pattern with separation of View and ViewModel. To solve your issue you can use DataTemplates along with a DataTemplateSelector. Basically you should prepare different Data templates and depends on internal state of applicaiton / a particular ViewModel switch Views (XAML layouts).
1) Define all templates in resources:
<!-- namespace where GridView .xaml and ChartView .xaml are -->
xmlns:views="clr-namespace:Gui.Views"
...
<DataTemplate x:Key="GridDataTemplate">
<views:GridView />
</DataTemplate>
<DataTemplate x:Key="ChartDataTemplate">
<views:ChartView />
</DataTemplate>
2) Specify selector in Control's presenter:
<Control....
<ContentPresenter
ContentTemplateSelector="{StaticResource YourDataTemplateSelector}" />
3) Define selector in View's code behind:
private sealed class YourDataTemplateSelector: DataTemplateSelector
{
public override DataTemplate SelectTemplate(
object item,
DependencyObject container)
{
DataTemplate dataTemplate = null;
IViewModel viewModel = item as IViewModel;
if (viewModel.ViewType == Grid)
{
dataTemplate = this.Resources["GridDataTemplate"];
}
// ...
return dataTemplate;
}
}
EDIT: Dynamically build controls
- You can use VisualTreeHelper.GetChild() to traverse controls tree, find children controls, check whether they are of specific type and then remove/update
- You can reffer parent control by
control.Parent
property - You can remove any child control using
(parent as Panel).Children.Remove()
- You can add control using
(parent as Panel).Children.Add()
You could use ContentControl
s? They give you ability to dynamically host any control based on user actions. ContentControl
s are like visual placeholders.
http://www.japf.fr/2009/03/thinking-with-mvvm-data-templates-contentcontrol/
You can always use Trigger
s to replace content os a content control dynamcially...
<StackPanel>
<TextBlock Text="{Binding Name}" />
<ContentControl Content="{Binding}">
<ContentControl.Style>
<Style>
<Setter ContentTemplate="{StaticResource EmployeeTemplate}" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsManager}"
Value="True">
<Setter ContentTemplate="{StaticResource ManagerTemplate}" />
</DataTrigger>
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
</StackPanel>
So based on if the bound Employee
object has IsManager=true
a new template is dipslayed under the stack panel for the manager employee..
精彩评论