开发者

WPF Control Manipulation

开发者 https://www.devze.com 2023-04-13 05:51 出处:网络
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...

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..

  1. In Mapper I need to create instance for Button Label with (+),
  2. I need to create a Panel., ie., Container for holding both the Controls (ComboBox,Button)
  3. 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 ContentControls? They give you ability to dynamically host any control based on user actions. ContentControls are like visual placeholders.

http://www.japf.fr/2009/03/thinking-with-mvvm-data-templates-contentcontrol/

You can always use Triggers 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..

0

精彩评论

暂无评论...
验证码 换一张
取 消