WPF, how to destroy and recreate usercontrol based on changes in other, & binding problem











up vote
0
down vote

favorite












I am new to WPF and C#,



I have a main screen consist of multiple user controls and some of the need to be destroyed and recreate on the fly based on the selection of one.



Here is my sample WMMW code,



Models



public class Method : INotifyPropertyChanged, IDataErrorInfo
{
#region properties

private string _method;
private string _helper;

#endregion

public Method()
{
_method = "MM1";
_helper = "HM1";
}
//getter setters..
}

public class Property : INotifyPropertyChanged
{
#region Properties

private string _name;
private string _path;
private float _standarddeviation;
private string _unit;

//getter setters
}


MethodViewModel



    class MethodViewModel
{
#region Properties

private Method _method;

#endregion



#region Getter & Setters

public Method Method
{
get { return _method; }

}

public ICommand UpdateCommand
{
get; private set;
}
#endregion

#region Constructor
/// <summary>
/// Initialize a new interface of the MEthodViewModel class
/// </summary>
public MethodViewModel()
{
//test
_method = new Method();
UpdateCommand = new MethodUpdateCommand(this);
}
#endregion


#region Functions



public void SaveChanges()
{

//TODO: Destroy and rebuild the usercontrol

}

#endregion


}


Command



    class MethodUpdateCommand : ICommand
{
private MethodViewModel _viewModel;


/// <summary>
/// Initialize a new instance of MethodNameUpdate Command
/// </summary>
/// <param name="viewModel"></param>
public MethodUpdateCommand(MethodViewModel viewModel)
{
_viewModel = viewModel;
}



#region ICOmmand Members

public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}


public bool CanExecute(object parameter)
{
return String.IsNullOrWhiteSpace(_viewModel.Method.Error);
}

public void Execute(object parameter)
{
_viewModel.SaveChanges();
}

#endregion
}


Main screen



<Window x:Class="WpfApplicationTest.Views.MainScreen"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApplicationTest.Views"
xmlns:control="clr-namespace:WpfApplicationTest.Controls"

mc:Ignorable="d"
Title="MainScreen" Height="573.763" Width="354.839">
<Grid Margin="0,0,0,-41">
<control:MethodControl Margin="21,23,63,460" RenderTransformOrigin="0.507,0.567"></control:MethodControl>

<control:PropertyControl Margin="0,129,0,-129"></control:PropertyControl>

</Grid>




Method Control



<UserControl x:Class="WpfApplicationTest.Controls.MethodControl"
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:WpfApplicationTest.Controls"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
mc:Ignorable="d" d:DesignWidth="300" Height="101.075">

<WrapPanel Orientation=" Horizontal" VerticalAlignment="Top" Height="120" >
<Label Content="Method Name:" Width="113"/>
<ComboBox Width="160" SelectedItem="{Binding Method.Name, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" ItemsSource="{StaticResource MethodNames}" >
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<i:InvokeCommandAction Command="{Binding UpdateCommand}"/>
</i:EventTrigger>

</i:Interaction.Triggers>

</ComboBox>
<Label Content="Reflection Type:" Width="113"/>
<ComboBox Width="160" SelectedItem="{Binding Method.Helper, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" ItemsSource="{StaticResource HelperMethods}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<i:InvokeCommandAction Command="{Binding UpdateCommand}"/>
</i:EventTrigger>

</i:Interaction.Triggers>
</ComboBox>


</WrapPanel>




Property control.xaml





    <StackPanel Name="Test"></StackPanel>




    public partial class PropertyControl : UserControl
{
public PropertyControl()
{
InitializeComponent();
PopulatePropertyPanel("MM1", "HM1");
}

private void PopulatePropertyPanel(string name, string reflection)
{
//TODO: decide which mthod
//int methodindex = Constant.GetMethodNameIndex(name);
int methodindex = Array.IndexOf((String)Application.Current.Resources["MethodNames"], name);


switch (methodindex)
{
case 0:

foreach (String prop in (String)Application.Current.Resources["Result1"])
{

PopulateProperty(prop, true);


}
break;

default:

foreach (String prop in (String)Application.Current.Resources["Result2"])
{

PopulateProperty(prop, false);
}
break;
}


}

private void PopulateProperty(string prop, Boolean constant)
{


Label lbl = new Label();
lbl.Content = prop;
TextBox pathtext = new TextBox();
pathtext.Text = "path";
TextBox std = new TextBox();
std.Text = "std";
TextBox unit = new TextBox();
unit.Text = "unit";

Test.Children.Add(lbl);
Test.Children.Add(pathtext);
Test.Children.Add(std);
Test.Children.Add(unit);


}
}


I want to recreate populate property-control, every time there is a change in method-control, which I already create a command for it.



Also, how can I bind the components in property control with property model,
I need to have a collection of properties (1 property for each result, and destroy and rebuild the collection with property-control.



EDIT 1:



Main window





    <ContentControl Grid.Row="1" Content="{Binding ChildViewModel}" />


Resources



 <DataTemplate DataType="{x:Type modelViews:PropertyViewModel}">
<control:PropertyControl />
</DataTemplate>


MainViewModel



 class MethodViewModel : INotifyPropertyChanged
{
#region Properties

private Method _method;
private PropertyViewModel _childViewModel;



#endregion


#region Getter & Setters


public PropertyViewModel ChildViewModel
{
get { return this._childViewModel; }
set
{
if (this._childViewModel != value)
{
this._childViewModel = value;
OnPropertyChanged("ChildViewModel");
}
}
}
public MethodViewModel()
{
//test
_method = new Method();
_childViewModel = new PropertyViewModel();
_childViewModel.CollectProperties(_method.Name, _method.Helper);



UpdateCommand = new MethodUpdateCommand(this);


}

public void SaveChanges()
{

ChildViewModel = new PropertyViewModel(_method.Name,
_method.Helper);

}
}


ChildView



class PropertyViewModel : INotifyPropertyChanged
{

private ObservableCollection<Property> _properties;

public ObservableCollection<Property> Properties
{
get { return _properties; }
//set { _properties = value; }
}

public PropertyViewModel(string method, string reflection)
{
_properties = new ObservableCollection<Property>();

CollectProperties(method, reflection);
}


Property control .xaml



<StackPanel x:Name="Test" Grid.Row="1">
<ItemsControl ItemsSource = "{Binding ChildViewModel.Properties}">
<ItemsControl.ItemTemplate>
<DataTemplate>



<StackPanel Orientation = "Horizontal">
<Label Content="{Binding Name}"></Label>
<TextBox Text = "{Binding Path, Mode=TwoWay}"
Width = "100" Margin = "3 5 3 5"/>

<TextBox Text = "{Binding StdDev, Mode=TwoWay}"
Width = "100" Margin = "3 5 3 5"/>

<TextBox Text = "{Binding Unit, Mode=TwoWay}"
Width = "100" Margin = "3 5 3 5"/>

</StackPanel>

</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>


My child view is updated in the debugger, but the view is not updated, I am not sure what am I missing










share|improve this question




























    up vote
    0
    down vote

    favorite












    I am new to WPF and C#,



    I have a main screen consist of multiple user controls and some of the need to be destroyed and recreate on the fly based on the selection of one.



    Here is my sample WMMW code,



    Models



    public class Method : INotifyPropertyChanged, IDataErrorInfo
    {
    #region properties

    private string _method;
    private string _helper;

    #endregion

    public Method()
    {
    _method = "MM1";
    _helper = "HM1";
    }
    //getter setters..
    }

    public class Property : INotifyPropertyChanged
    {
    #region Properties

    private string _name;
    private string _path;
    private float _standarddeviation;
    private string _unit;

    //getter setters
    }


    MethodViewModel



        class MethodViewModel
    {
    #region Properties

    private Method _method;

    #endregion



    #region Getter & Setters

    public Method Method
    {
    get { return _method; }

    }

    public ICommand UpdateCommand
    {
    get; private set;
    }
    #endregion

    #region Constructor
    /// <summary>
    /// Initialize a new interface of the MEthodViewModel class
    /// </summary>
    public MethodViewModel()
    {
    //test
    _method = new Method();
    UpdateCommand = new MethodUpdateCommand(this);
    }
    #endregion


    #region Functions



    public void SaveChanges()
    {

    //TODO: Destroy and rebuild the usercontrol

    }

    #endregion


    }


    Command



        class MethodUpdateCommand : ICommand
    {
    private MethodViewModel _viewModel;


    /// <summary>
    /// Initialize a new instance of MethodNameUpdate Command
    /// </summary>
    /// <param name="viewModel"></param>
    public MethodUpdateCommand(MethodViewModel viewModel)
    {
    _viewModel = viewModel;
    }



    #region ICOmmand Members

    public event EventHandler CanExecuteChanged
    {
    add { CommandManager.RequerySuggested += value; }
    remove { CommandManager.RequerySuggested -= value; }
    }


    public bool CanExecute(object parameter)
    {
    return String.IsNullOrWhiteSpace(_viewModel.Method.Error);
    }

    public void Execute(object parameter)
    {
    _viewModel.SaveChanges();
    }

    #endregion
    }


    Main screen



    <Window x:Class="WpfApplicationTest.Views.MainScreen"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:WpfApplicationTest.Views"
    xmlns:control="clr-namespace:WpfApplicationTest.Controls"

    mc:Ignorable="d"
    Title="MainScreen" Height="573.763" Width="354.839">
    <Grid Margin="0,0,0,-41">
    <control:MethodControl Margin="21,23,63,460" RenderTransformOrigin="0.507,0.567"></control:MethodControl>

    <control:PropertyControl Margin="0,129,0,-129"></control:PropertyControl>

    </Grid>




    Method Control



    <UserControl x:Class="WpfApplicationTest.Controls.MethodControl"
    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:WpfApplicationTest.Controls"
    xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
    mc:Ignorable="d" d:DesignWidth="300" Height="101.075">

    <WrapPanel Orientation=" Horizontal" VerticalAlignment="Top" Height="120" >
    <Label Content="Method Name:" Width="113"/>
    <ComboBox Width="160" SelectedItem="{Binding Method.Name, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" ItemsSource="{StaticResource MethodNames}" >
    <i:Interaction.Triggers>
    <i:EventTrigger EventName="SelectionChanged">
    <i:InvokeCommandAction Command="{Binding UpdateCommand}"/>
    </i:EventTrigger>

    </i:Interaction.Triggers>

    </ComboBox>
    <Label Content="Reflection Type:" Width="113"/>
    <ComboBox Width="160" SelectedItem="{Binding Method.Helper, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" ItemsSource="{StaticResource HelperMethods}">
    <i:Interaction.Triggers>
    <i:EventTrigger EventName="SelectionChanged">
    <i:InvokeCommandAction Command="{Binding UpdateCommand}"/>
    </i:EventTrigger>

    </i:Interaction.Triggers>
    </ComboBox>


    </WrapPanel>




    Property control.xaml





        <StackPanel Name="Test"></StackPanel>




        public partial class PropertyControl : UserControl
    {
    public PropertyControl()
    {
    InitializeComponent();
    PopulatePropertyPanel("MM1", "HM1");
    }

    private void PopulatePropertyPanel(string name, string reflection)
    {
    //TODO: decide which mthod
    //int methodindex = Constant.GetMethodNameIndex(name);
    int methodindex = Array.IndexOf((String)Application.Current.Resources["MethodNames"], name);


    switch (methodindex)
    {
    case 0:

    foreach (String prop in (String)Application.Current.Resources["Result1"])
    {

    PopulateProperty(prop, true);


    }
    break;

    default:

    foreach (String prop in (String)Application.Current.Resources["Result2"])
    {

    PopulateProperty(prop, false);
    }
    break;
    }


    }

    private void PopulateProperty(string prop, Boolean constant)
    {


    Label lbl = new Label();
    lbl.Content = prop;
    TextBox pathtext = new TextBox();
    pathtext.Text = "path";
    TextBox std = new TextBox();
    std.Text = "std";
    TextBox unit = new TextBox();
    unit.Text = "unit";

    Test.Children.Add(lbl);
    Test.Children.Add(pathtext);
    Test.Children.Add(std);
    Test.Children.Add(unit);


    }
    }


    I want to recreate populate property-control, every time there is a change in method-control, which I already create a command for it.



    Also, how can I bind the components in property control with property model,
    I need to have a collection of properties (1 property for each result, and destroy and rebuild the collection with property-control.



    EDIT 1:



    Main window





        <ContentControl Grid.Row="1" Content="{Binding ChildViewModel}" />


    Resources



     <DataTemplate DataType="{x:Type modelViews:PropertyViewModel}">
    <control:PropertyControl />
    </DataTemplate>


    MainViewModel



     class MethodViewModel : INotifyPropertyChanged
    {
    #region Properties

    private Method _method;
    private PropertyViewModel _childViewModel;



    #endregion


    #region Getter & Setters


    public PropertyViewModel ChildViewModel
    {
    get { return this._childViewModel; }
    set
    {
    if (this._childViewModel != value)
    {
    this._childViewModel = value;
    OnPropertyChanged("ChildViewModel");
    }
    }
    }
    public MethodViewModel()
    {
    //test
    _method = new Method();
    _childViewModel = new PropertyViewModel();
    _childViewModel.CollectProperties(_method.Name, _method.Helper);



    UpdateCommand = new MethodUpdateCommand(this);


    }

    public void SaveChanges()
    {

    ChildViewModel = new PropertyViewModel(_method.Name,
    _method.Helper);

    }
    }


    ChildView



    class PropertyViewModel : INotifyPropertyChanged
    {

    private ObservableCollection<Property> _properties;

    public ObservableCollection<Property> Properties
    {
    get { return _properties; }
    //set { _properties = value; }
    }

    public PropertyViewModel(string method, string reflection)
    {
    _properties = new ObservableCollection<Property>();

    CollectProperties(method, reflection);
    }


    Property control .xaml



    <StackPanel x:Name="Test" Grid.Row="1">
    <ItemsControl ItemsSource = "{Binding ChildViewModel.Properties}">
    <ItemsControl.ItemTemplate>
    <DataTemplate>



    <StackPanel Orientation = "Horizontal">
    <Label Content="{Binding Name}"></Label>
    <TextBox Text = "{Binding Path, Mode=TwoWay}"
    Width = "100" Margin = "3 5 3 5"/>

    <TextBox Text = "{Binding StdDev, Mode=TwoWay}"
    Width = "100" Margin = "3 5 3 5"/>

    <TextBox Text = "{Binding Unit, Mode=TwoWay}"
    Width = "100" Margin = "3 5 3 5"/>

    </StackPanel>

    </DataTemplate>
    </ItemsControl.ItemTemplate>
    </ItemsControl>
    </StackPanel>


    My child view is updated in the debugger, but the view is not updated, I am not sure what am I missing










    share|improve this question


























      up vote
      0
      down vote

      favorite









      up vote
      0
      down vote

      favorite











      I am new to WPF and C#,



      I have a main screen consist of multiple user controls and some of the need to be destroyed and recreate on the fly based on the selection of one.



      Here is my sample WMMW code,



      Models



      public class Method : INotifyPropertyChanged, IDataErrorInfo
      {
      #region properties

      private string _method;
      private string _helper;

      #endregion

      public Method()
      {
      _method = "MM1";
      _helper = "HM1";
      }
      //getter setters..
      }

      public class Property : INotifyPropertyChanged
      {
      #region Properties

      private string _name;
      private string _path;
      private float _standarddeviation;
      private string _unit;

      //getter setters
      }


      MethodViewModel



          class MethodViewModel
      {
      #region Properties

      private Method _method;

      #endregion



      #region Getter & Setters

      public Method Method
      {
      get { return _method; }

      }

      public ICommand UpdateCommand
      {
      get; private set;
      }
      #endregion

      #region Constructor
      /// <summary>
      /// Initialize a new interface of the MEthodViewModel class
      /// </summary>
      public MethodViewModel()
      {
      //test
      _method = new Method();
      UpdateCommand = new MethodUpdateCommand(this);
      }
      #endregion


      #region Functions



      public void SaveChanges()
      {

      //TODO: Destroy and rebuild the usercontrol

      }

      #endregion


      }


      Command



          class MethodUpdateCommand : ICommand
      {
      private MethodViewModel _viewModel;


      /// <summary>
      /// Initialize a new instance of MethodNameUpdate Command
      /// </summary>
      /// <param name="viewModel"></param>
      public MethodUpdateCommand(MethodViewModel viewModel)
      {
      _viewModel = viewModel;
      }



      #region ICOmmand Members

      public event EventHandler CanExecuteChanged
      {
      add { CommandManager.RequerySuggested += value; }
      remove { CommandManager.RequerySuggested -= value; }
      }


      public bool CanExecute(object parameter)
      {
      return String.IsNullOrWhiteSpace(_viewModel.Method.Error);
      }

      public void Execute(object parameter)
      {
      _viewModel.SaveChanges();
      }

      #endregion
      }


      Main screen



      <Window x:Class="WpfApplicationTest.Views.MainScreen"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
      xmlns:local="clr-namespace:WpfApplicationTest.Views"
      xmlns:control="clr-namespace:WpfApplicationTest.Controls"

      mc:Ignorable="d"
      Title="MainScreen" Height="573.763" Width="354.839">
      <Grid Margin="0,0,0,-41">
      <control:MethodControl Margin="21,23,63,460" RenderTransformOrigin="0.507,0.567"></control:MethodControl>

      <control:PropertyControl Margin="0,129,0,-129"></control:PropertyControl>

      </Grid>




      Method Control



      <UserControl x:Class="WpfApplicationTest.Controls.MethodControl"
      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:WpfApplicationTest.Controls"
      xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
      mc:Ignorable="d" d:DesignWidth="300" Height="101.075">

      <WrapPanel Orientation=" Horizontal" VerticalAlignment="Top" Height="120" >
      <Label Content="Method Name:" Width="113"/>
      <ComboBox Width="160" SelectedItem="{Binding Method.Name, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" ItemsSource="{StaticResource MethodNames}" >
      <i:Interaction.Triggers>
      <i:EventTrigger EventName="SelectionChanged">
      <i:InvokeCommandAction Command="{Binding UpdateCommand}"/>
      </i:EventTrigger>

      </i:Interaction.Triggers>

      </ComboBox>
      <Label Content="Reflection Type:" Width="113"/>
      <ComboBox Width="160" SelectedItem="{Binding Method.Helper, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" ItemsSource="{StaticResource HelperMethods}">
      <i:Interaction.Triggers>
      <i:EventTrigger EventName="SelectionChanged">
      <i:InvokeCommandAction Command="{Binding UpdateCommand}"/>
      </i:EventTrigger>

      </i:Interaction.Triggers>
      </ComboBox>


      </WrapPanel>




      Property control.xaml





          <StackPanel Name="Test"></StackPanel>




          public partial class PropertyControl : UserControl
      {
      public PropertyControl()
      {
      InitializeComponent();
      PopulatePropertyPanel("MM1", "HM1");
      }

      private void PopulatePropertyPanel(string name, string reflection)
      {
      //TODO: decide which mthod
      //int methodindex = Constant.GetMethodNameIndex(name);
      int methodindex = Array.IndexOf((String)Application.Current.Resources["MethodNames"], name);


      switch (methodindex)
      {
      case 0:

      foreach (String prop in (String)Application.Current.Resources["Result1"])
      {

      PopulateProperty(prop, true);


      }
      break;

      default:

      foreach (String prop in (String)Application.Current.Resources["Result2"])
      {

      PopulateProperty(prop, false);
      }
      break;
      }


      }

      private void PopulateProperty(string prop, Boolean constant)
      {


      Label lbl = new Label();
      lbl.Content = prop;
      TextBox pathtext = new TextBox();
      pathtext.Text = "path";
      TextBox std = new TextBox();
      std.Text = "std";
      TextBox unit = new TextBox();
      unit.Text = "unit";

      Test.Children.Add(lbl);
      Test.Children.Add(pathtext);
      Test.Children.Add(std);
      Test.Children.Add(unit);


      }
      }


      I want to recreate populate property-control, every time there is a change in method-control, which I already create a command for it.



      Also, how can I bind the components in property control with property model,
      I need to have a collection of properties (1 property for each result, and destroy and rebuild the collection with property-control.



      EDIT 1:



      Main window





          <ContentControl Grid.Row="1" Content="{Binding ChildViewModel}" />


      Resources



       <DataTemplate DataType="{x:Type modelViews:PropertyViewModel}">
      <control:PropertyControl />
      </DataTemplate>


      MainViewModel



       class MethodViewModel : INotifyPropertyChanged
      {
      #region Properties

      private Method _method;
      private PropertyViewModel _childViewModel;



      #endregion


      #region Getter & Setters


      public PropertyViewModel ChildViewModel
      {
      get { return this._childViewModel; }
      set
      {
      if (this._childViewModel != value)
      {
      this._childViewModel = value;
      OnPropertyChanged("ChildViewModel");
      }
      }
      }
      public MethodViewModel()
      {
      //test
      _method = new Method();
      _childViewModel = new PropertyViewModel();
      _childViewModel.CollectProperties(_method.Name, _method.Helper);



      UpdateCommand = new MethodUpdateCommand(this);


      }

      public void SaveChanges()
      {

      ChildViewModel = new PropertyViewModel(_method.Name,
      _method.Helper);

      }
      }


      ChildView



      class PropertyViewModel : INotifyPropertyChanged
      {

      private ObservableCollection<Property> _properties;

      public ObservableCollection<Property> Properties
      {
      get { return _properties; }
      //set { _properties = value; }
      }

      public PropertyViewModel(string method, string reflection)
      {
      _properties = new ObservableCollection<Property>();

      CollectProperties(method, reflection);
      }


      Property control .xaml



      <StackPanel x:Name="Test" Grid.Row="1">
      <ItemsControl ItemsSource = "{Binding ChildViewModel.Properties}">
      <ItemsControl.ItemTemplate>
      <DataTemplate>



      <StackPanel Orientation = "Horizontal">
      <Label Content="{Binding Name}"></Label>
      <TextBox Text = "{Binding Path, Mode=TwoWay}"
      Width = "100" Margin = "3 5 3 5"/>

      <TextBox Text = "{Binding StdDev, Mode=TwoWay}"
      Width = "100" Margin = "3 5 3 5"/>

      <TextBox Text = "{Binding Unit, Mode=TwoWay}"
      Width = "100" Margin = "3 5 3 5"/>

      </StackPanel>

      </DataTemplate>
      </ItemsControl.ItemTemplate>
      </ItemsControl>
      </StackPanel>


      My child view is updated in the debugger, but the view is not updated, I am not sure what am I missing










      share|improve this question















      I am new to WPF and C#,



      I have a main screen consist of multiple user controls and some of the need to be destroyed and recreate on the fly based on the selection of one.



      Here is my sample WMMW code,



      Models



      public class Method : INotifyPropertyChanged, IDataErrorInfo
      {
      #region properties

      private string _method;
      private string _helper;

      #endregion

      public Method()
      {
      _method = "MM1";
      _helper = "HM1";
      }
      //getter setters..
      }

      public class Property : INotifyPropertyChanged
      {
      #region Properties

      private string _name;
      private string _path;
      private float _standarddeviation;
      private string _unit;

      //getter setters
      }


      MethodViewModel



          class MethodViewModel
      {
      #region Properties

      private Method _method;

      #endregion



      #region Getter & Setters

      public Method Method
      {
      get { return _method; }

      }

      public ICommand UpdateCommand
      {
      get; private set;
      }
      #endregion

      #region Constructor
      /// <summary>
      /// Initialize a new interface of the MEthodViewModel class
      /// </summary>
      public MethodViewModel()
      {
      //test
      _method = new Method();
      UpdateCommand = new MethodUpdateCommand(this);
      }
      #endregion


      #region Functions



      public void SaveChanges()
      {

      //TODO: Destroy and rebuild the usercontrol

      }

      #endregion


      }


      Command



          class MethodUpdateCommand : ICommand
      {
      private MethodViewModel _viewModel;


      /// <summary>
      /// Initialize a new instance of MethodNameUpdate Command
      /// </summary>
      /// <param name="viewModel"></param>
      public MethodUpdateCommand(MethodViewModel viewModel)
      {
      _viewModel = viewModel;
      }



      #region ICOmmand Members

      public event EventHandler CanExecuteChanged
      {
      add { CommandManager.RequerySuggested += value; }
      remove { CommandManager.RequerySuggested -= value; }
      }


      public bool CanExecute(object parameter)
      {
      return String.IsNullOrWhiteSpace(_viewModel.Method.Error);
      }

      public void Execute(object parameter)
      {
      _viewModel.SaveChanges();
      }

      #endregion
      }


      Main screen



      <Window x:Class="WpfApplicationTest.Views.MainScreen"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
      xmlns:local="clr-namespace:WpfApplicationTest.Views"
      xmlns:control="clr-namespace:WpfApplicationTest.Controls"

      mc:Ignorable="d"
      Title="MainScreen" Height="573.763" Width="354.839">
      <Grid Margin="0,0,0,-41">
      <control:MethodControl Margin="21,23,63,460" RenderTransformOrigin="0.507,0.567"></control:MethodControl>

      <control:PropertyControl Margin="0,129,0,-129"></control:PropertyControl>

      </Grid>




      Method Control



      <UserControl x:Class="WpfApplicationTest.Controls.MethodControl"
      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:WpfApplicationTest.Controls"
      xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
      mc:Ignorable="d" d:DesignWidth="300" Height="101.075">

      <WrapPanel Orientation=" Horizontal" VerticalAlignment="Top" Height="120" >
      <Label Content="Method Name:" Width="113"/>
      <ComboBox Width="160" SelectedItem="{Binding Method.Name, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" ItemsSource="{StaticResource MethodNames}" >
      <i:Interaction.Triggers>
      <i:EventTrigger EventName="SelectionChanged">
      <i:InvokeCommandAction Command="{Binding UpdateCommand}"/>
      </i:EventTrigger>

      </i:Interaction.Triggers>

      </ComboBox>
      <Label Content="Reflection Type:" Width="113"/>
      <ComboBox Width="160" SelectedItem="{Binding Method.Helper, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" ItemsSource="{StaticResource HelperMethods}">
      <i:Interaction.Triggers>
      <i:EventTrigger EventName="SelectionChanged">
      <i:InvokeCommandAction Command="{Binding UpdateCommand}"/>
      </i:EventTrigger>

      </i:Interaction.Triggers>
      </ComboBox>


      </WrapPanel>




      Property control.xaml





          <StackPanel Name="Test"></StackPanel>




          public partial class PropertyControl : UserControl
      {
      public PropertyControl()
      {
      InitializeComponent();
      PopulatePropertyPanel("MM1", "HM1");
      }

      private void PopulatePropertyPanel(string name, string reflection)
      {
      //TODO: decide which mthod
      //int methodindex = Constant.GetMethodNameIndex(name);
      int methodindex = Array.IndexOf((String)Application.Current.Resources["MethodNames"], name);


      switch (methodindex)
      {
      case 0:

      foreach (String prop in (String)Application.Current.Resources["Result1"])
      {

      PopulateProperty(prop, true);


      }
      break;

      default:

      foreach (String prop in (String)Application.Current.Resources["Result2"])
      {

      PopulateProperty(prop, false);
      }
      break;
      }


      }

      private void PopulateProperty(string prop, Boolean constant)
      {


      Label lbl = new Label();
      lbl.Content = prop;
      TextBox pathtext = new TextBox();
      pathtext.Text = "path";
      TextBox std = new TextBox();
      std.Text = "std";
      TextBox unit = new TextBox();
      unit.Text = "unit";

      Test.Children.Add(lbl);
      Test.Children.Add(pathtext);
      Test.Children.Add(std);
      Test.Children.Add(unit);


      }
      }


      I want to recreate populate property-control, every time there is a change in method-control, which I already create a command for it.



      Also, how can I bind the components in property control with property model,
      I need to have a collection of properties (1 property for each result, and destroy and rebuild the collection with property-control.



      EDIT 1:



      Main window





          <ContentControl Grid.Row="1" Content="{Binding ChildViewModel}" />


      Resources



       <DataTemplate DataType="{x:Type modelViews:PropertyViewModel}">
      <control:PropertyControl />
      </DataTemplate>


      MainViewModel



       class MethodViewModel : INotifyPropertyChanged
      {
      #region Properties

      private Method _method;
      private PropertyViewModel _childViewModel;



      #endregion


      #region Getter & Setters


      public PropertyViewModel ChildViewModel
      {
      get { return this._childViewModel; }
      set
      {
      if (this._childViewModel != value)
      {
      this._childViewModel = value;
      OnPropertyChanged("ChildViewModel");
      }
      }
      }
      public MethodViewModel()
      {
      //test
      _method = new Method();
      _childViewModel = new PropertyViewModel();
      _childViewModel.CollectProperties(_method.Name, _method.Helper);



      UpdateCommand = new MethodUpdateCommand(this);


      }

      public void SaveChanges()
      {

      ChildViewModel = new PropertyViewModel(_method.Name,
      _method.Helper);

      }
      }


      ChildView



      class PropertyViewModel : INotifyPropertyChanged
      {

      private ObservableCollection<Property> _properties;

      public ObservableCollection<Property> Properties
      {
      get { return _properties; }
      //set { _properties = value; }
      }

      public PropertyViewModel(string method, string reflection)
      {
      _properties = new ObservableCollection<Property>();

      CollectProperties(method, reflection);
      }


      Property control .xaml



      <StackPanel x:Name="Test" Grid.Row="1">
      <ItemsControl ItemsSource = "{Binding ChildViewModel.Properties}">
      <ItemsControl.ItemTemplate>
      <DataTemplate>



      <StackPanel Orientation = "Horizontal">
      <Label Content="{Binding Name}"></Label>
      <TextBox Text = "{Binding Path, Mode=TwoWay}"
      Width = "100" Margin = "3 5 3 5"/>

      <TextBox Text = "{Binding StdDev, Mode=TwoWay}"
      Width = "100" Margin = "3 5 3 5"/>

      <TextBox Text = "{Binding Unit, Mode=TwoWay}"
      Width = "100" Margin = "3 5 3 5"/>

      </StackPanel>

      </DataTemplate>
      </ItemsControl.ItemTemplate>
      </ItemsControl>
      </StackPanel>


      My child view is updated in the debugger, but the view is not updated, I am not sure what am I missing







      wpf dynamic data-binding user-controls






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited yesterday

























      asked 2 days ago









      Guray Golcuk

      174




      174
























          1 Answer
          1






          active

          oldest

          votes

















          up vote
          1
          down vote



          accepted










          In general you solve this with ContentControls and DataTemplates. Let's say you have a MainViewModel and you want to be able to display a child view model, so you start by exposing a property with property change notification, i.e. something like this:



              private object _MyChild;
          public object MyChild
          {
          get { return this._MyChild; }
          set
          {
          if (this._MyChild != value)
          {
          this._MyChild = value;
          RaisePropertyChanged(() => this.MyChild);
          }
          }
          }


          Over in the XAML for your main window you create a content control and bind it to this property:



          <ContentControl Content="{Binding MyChild}" />


          Finally in your resources block you create a DataTemplate for each child view model that you might assign to this property:



          <DataTemplate DataType="{x:Type local:ChildViewModel}">
          <local:ChildViewControl />
          </DataTemplate>


          <DataTemplate DataType="{x:Type local:ChildViewModel2}">
          <local:ChildViewControl2 />
          </DataTemplate>

          ... etc...


          Ordinarily this control won't be visible, but as soon as you assign an appropriate view model to the property it will automatically populate based on what you've specified in your data templates:



          this.MyChild = new ChildViewModel(); // <-- child control gets created and appears


          In practice your property wouldn't be of type object, you usually have some base class that all your child view models are derived from, but you get the idea.



          There are other ways to do this (e.g. DataTriggers) but DataTemplates are what you usually use for cases such as what you've described.



          UPDATE: Here's some fully working code, imagine your MainViewModel has a property for a child view model and a couple of button handlers to set and clear the child:



          public class MainViewModel : ViewModelBase
          {
          // Child property

          private ChildViewModel _Child;
          public ChildViewModel Child
          {
          get { return this._Child; }
          set
          {
          if (this._Child != value)
          {
          this._Child = value;
          RaisePropertyChanged(() => this.Child);
          }
          }
          }

          // Set child

          private ICommand _SetChildCommand;
          public ICommand SetChildCommand => this._SetChildCommand ?? (this._SetChildCommand = new RelayCommand(OnSetChild));

          private void OnSetChild()
          {
          this.Child = new ChildViewModel();
          }

          // Clear child

          private ICommand _ClearChildCommand;
          public ICommand ClearChildCommand => this._ClearChildCommand ?? (this._ClearChildCommand = new RelayCommand(OnClearChild));

          private void OnClearChild()
          {
          this.Child = null;
          }

          }

          public class ChildViewModel : ViewModelBase
          {
          public string Text => "I am child type 1!";
          }


          Then in your XAML all you need to do is this:



          <StackPanel Orientation="Horizontal" VerticalAlignment="Top" >
          <Button Content="Set Child" Command="{Binding SetChildCommand}" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="5" />
          <Button Content="Clear Child" Command="{Binding ClearChildCommand}" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="5" />


          <ContentControl Content="{Binding Child}">
          <ContentControl.Resources>
          <DataTemplate DataType="{x:Type local:ChildViewModel}">
          <TextBlock Text="{Binding Text}" Foreground="Yellow" Background="Blue" HorizontalAlignment="Left" VerticalAlignment="Center" />
          </DataTemplate>
          </ContentControl.Resources>
          </ContentControl>

          </StackPanel>


          Initially you'll only see the two buttons by themselves, but clicking on "Set Child" will cause the OnSetChild handler to get called, which will create a new instance of ChildViewModel and assign it to the property. Because of the DataTemplate the ContentControl will be automatically populated:



          enter image description here



          Likewise, clicking the "Clear child" button will clear the property and the yellow/blue text will disappear. (I'm using a TextBlock here but obviously you can use anything you want, including your own custom controls).






          share|improve this answer























          • Thank you, it helps me to solve some of my problems but I still couldn't manage with dynamic user-control change ` public object _model; public object _ childView ` I couldn't figure it out how the change in the model, updates the current model-control (destroy and recreate)
            – Guray Golcuk
            2 days ago








          • 1




            I don't really know how to describe it more clearly than that....if you bind a ContentControl to your data, and use a DataTemplate for your view model data type, the content of the DataTemplate will appear as a child of the ContentControl. Set the property to null and it'll be destroyed. If you still can't get it to work then post some code that uses ContentControl and DataTemplate and I'll tell you what you're doing wrong.
            – Mark Feldman
            yesterday






          • 1




            So when you put a breakpoint in OnSetChild it gets hit when you press the button? Have you made any other changes to the code at all?
            – Mark Feldman
            yesterday






          • 1




            In particular, is your property change notification the same i.e. MVVM Lite? Because if your call to RaisePropertyChanged is broken, or the parent class (MainViewModel) doesn't support property change notification, then it won't work.
            – Mark Feldman
            yesterday








          • 1




            In your property control you should be binding to Properties, not ChildViewModel.Properties. When you do a <ContentControl Content="{Binding ChildViewModel}" /> back in your main window xaml it already sets the DataContext for whatever is inside the ContentControl to the binding, i.e. ChildViewModel.
            – Mark Feldman
            yesterday











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














           

          draft saved


          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53187784%2fwpf-how-to-destroy-and-recreate-usercontrol-based-on-changes-in-other-bindin%23new-answer', 'question_page');
          }
          );

          Post as a guest
































          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          up vote
          1
          down vote



          accepted










          In general you solve this with ContentControls and DataTemplates. Let's say you have a MainViewModel and you want to be able to display a child view model, so you start by exposing a property with property change notification, i.e. something like this:



              private object _MyChild;
          public object MyChild
          {
          get { return this._MyChild; }
          set
          {
          if (this._MyChild != value)
          {
          this._MyChild = value;
          RaisePropertyChanged(() => this.MyChild);
          }
          }
          }


          Over in the XAML for your main window you create a content control and bind it to this property:



          <ContentControl Content="{Binding MyChild}" />


          Finally in your resources block you create a DataTemplate for each child view model that you might assign to this property:



          <DataTemplate DataType="{x:Type local:ChildViewModel}">
          <local:ChildViewControl />
          </DataTemplate>


          <DataTemplate DataType="{x:Type local:ChildViewModel2}">
          <local:ChildViewControl2 />
          </DataTemplate>

          ... etc...


          Ordinarily this control won't be visible, but as soon as you assign an appropriate view model to the property it will automatically populate based on what you've specified in your data templates:



          this.MyChild = new ChildViewModel(); // <-- child control gets created and appears


          In practice your property wouldn't be of type object, you usually have some base class that all your child view models are derived from, but you get the idea.



          There are other ways to do this (e.g. DataTriggers) but DataTemplates are what you usually use for cases such as what you've described.



          UPDATE: Here's some fully working code, imagine your MainViewModel has a property for a child view model and a couple of button handlers to set and clear the child:



          public class MainViewModel : ViewModelBase
          {
          // Child property

          private ChildViewModel _Child;
          public ChildViewModel Child
          {
          get { return this._Child; }
          set
          {
          if (this._Child != value)
          {
          this._Child = value;
          RaisePropertyChanged(() => this.Child);
          }
          }
          }

          // Set child

          private ICommand _SetChildCommand;
          public ICommand SetChildCommand => this._SetChildCommand ?? (this._SetChildCommand = new RelayCommand(OnSetChild));

          private void OnSetChild()
          {
          this.Child = new ChildViewModel();
          }

          // Clear child

          private ICommand _ClearChildCommand;
          public ICommand ClearChildCommand => this._ClearChildCommand ?? (this._ClearChildCommand = new RelayCommand(OnClearChild));

          private void OnClearChild()
          {
          this.Child = null;
          }

          }

          public class ChildViewModel : ViewModelBase
          {
          public string Text => "I am child type 1!";
          }


          Then in your XAML all you need to do is this:



          <StackPanel Orientation="Horizontal" VerticalAlignment="Top" >
          <Button Content="Set Child" Command="{Binding SetChildCommand}" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="5" />
          <Button Content="Clear Child" Command="{Binding ClearChildCommand}" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="5" />


          <ContentControl Content="{Binding Child}">
          <ContentControl.Resources>
          <DataTemplate DataType="{x:Type local:ChildViewModel}">
          <TextBlock Text="{Binding Text}" Foreground="Yellow" Background="Blue" HorizontalAlignment="Left" VerticalAlignment="Center" />
          </DataTemplate>
          </ContentControl.Resources>
          </ContentControl>

          </StackPanel>


          Initially you'll only see the two buttons by themselves, but clicking on "Set Child" will cause the OnSetChild handler to get called, which will create a new instance of ChildViewModel and assign it to the property. Because of the DataTemplate the ContentControl will be automatically populated:



          enter image description here



          Likewise, clicking the "Clear child" button will clear the property and the yellow/blue text will disappear. (I'm using a TextBlock here but obviously you can use anything you want, including your own custom controls).






          share|improve this answer























          • Thank you, it helps me to solve some of my problems but I still couldn't manage with dynamic user-control change ` public object _model; public object _ childView ` I couldn't figure it out how the change in the model, updates the current model-control (destroy and recreate)
            – Guray Golcuk
            2 days ago








          • 1




            I don't really know how to describe it more clearly than that....if you bind a ContentControl to your data, and use a DataTemplate for your view model data type, the content of the DataTemplate will appear as a child of the ContentControl. Set the property to null and it'll be destroyed. If you still can't get it to work then post some code that uses ContentControl and DataTemplate and I'll tell you what you're doing wrong.
            – Mark Feldman
            yesterday






          • 1




            So when you put a breakpoint in OnSetChild it gets hit when you press the button? Have you made any other changes to the code at all?
            – Mark Feldman
            yesterday






          • 1




            In particular, is your property change notification the same i.e. MVVM Lite? Because if your call to RaisePropertyChanged is broken, or the parent class (MainViewModel) doesn't support property change notification, then it won't work.
            – Mark Feldman
            yesterday








          • 1




            In your property control you should be binding to Properties, not ChildViewModel.Properties. When you do a <ContentControl Content="{Binding ChildViewModel}" /> back in your main window xaml it already sets the DataContext for whatever is inside the ContentControl to the binding, i.e. ChildViewModel.
            – Mark Feldman
            yesterday















          up vote
          1
          down vote



          accepted










          In general you solve this with ContentControls and DataTemplates. Let's say you have a MainViewModel and you want to be able to display a child view model, so you start by exposing a property with property change notification, i.e. something like this:



              private object _MyChild;
          public object MyChild
          {
          get { return this._MyChild; }
          set
          {
          if (this._MyChild != value)
          {
          this._MyChild = value;
          RaisePropertyChanged(() => this.MyChild);
          }
          }
          }


          Over in the XAML for your main window you create a content control and bind it to this property:



          <ContentControl Content="{Binding MyChild}" />


          Finally in your resources block you create a DataTemplate for each child view model that you might assign to this property:



          <DataTemplate DataType="{x:Type local:ChildViewModel}">
          <local:ChildViewControl />
          </DataTemplate>


          <DataTemplate DataType="{x:Type local:ChildViewModel2}">
          <local:ChildViewControl2 />
          </DataTemplate>

          ... etc...


          Ordinarily this control won't be visible, but as soon as you assign an appropriate view model to the property it will automatically populate based on what you've specified in your data templates:



          this.MyChild = new ChildViewModel(); // <-- child control gets created and appears


          In practice your property wouldn't be of type object, you usually have some base class that all your child view models are derived from, but you get the idea.



          There are other ways to do this (e.g. DataTriggers) but DataTemplates are what you usually use for cases such as what you've described.



          UPDATE: Here's some fully working code, imagine your MainViewModel has a property for a child view model and a couple of button handlers to set and clear the child:



          public class MainViewModel : ViewModelBase
          {
          // Child property

          private ChildViewModel _Child;
          public ChildViewModel Child
          {
          get { return this._Child; }
          set
          {
          if (this._Child != value)
          {
          this._Child = value;
          RaisePropertyChanged(() => this.Child);
          }
          }
          }

          // Set child

          private ICommand _SetChildCommand;
          public ICommand SetChildCommand => this._SetChildCommand ?? (this._SetChildCommand = new RelayCommand(OnSetChild));

          private void OnSetChild()
          {
          this.Child = new ChildViewModel();
          }

          // Clear child

          private ICommand _ClearChildCommand;
          public ICommand ClearChildCommand => this._ClearChildCommand ?? (this._ClearChildCommand = new RelayCommand(OnClearChild));

          private void OnClearChild()
          {
          this.Child = null;
          }

          }

          public class ChildViewModel : ViewModelBase
          {
          public string Text => "I am child type 1!";
          }


          Then in your XAML all you need to do is this:



          <StackPanel Orientation="Horizontal" VerticalAlignment="Top" >
          <Button Content="Set Child" Command="{Binding SetChildCommand}" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="5" />
          <Button Content="Clear Child" Command="{Binding ClearChildCommand}" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="5" />


          <ContentControl Content="{Binding Child}">
          <ContentControl.Resources>
          <DataTemplate DataType="{x:Type local:ChildViewModel}">
          <TextBlock Text="{Binding Text}" Foreground="Yellow" Background="Blue" HorizontalAlignment="Left" VerticalAlignment="Center" />
          </DataTemplate>
          </ContentControl.Resources>
          </ContentControl>

          </StackPanel>


          Initially you'll only see the two buttons by themselves, but clicking on "Set Child" will cause the OnSetChild handler to get called, which will create a new instance of ChildViewModel and assign it to the property. Because of the DataTemplate the ContentControl will be automatically populated:



          enter image description here



          Likewise, clicking the "Clear child" button will clear the property and the yellow/blue text will disappear. (I'm using a TextBlock here but obviously you can use anything you want, including your own custom controls).






          share|improve this answer























          • Thank you, it helps me to solve some of my problems but I still couldn't manage with dynamic user-control change ` public object _model; public object _ childView ` I couldn't figure it out how the change in the model, updates the current model-control (destroy and recreate)
            – Guray Golcuk
            2 days ago








          • 1




            I don't really know how to describe it more clearly than that....if you bind a ContentControl to your data, and use a DataTemplate for your view model data type, the content of the DataTemplate will appear as a child of the ContentControl. Set the property to null and it'll be destroyed. If you still can't get it to work then post some code that uses ContentControl and DataTemplate and I'll tell you what you're doing wrong.
            – Mark Feldman
            yesterday






          • 1




            So when you put a breakpoint in OnSetChild it gets hit when you press the button? Have you made any other changes to the code at all?
            – Mark Feldman
            yesterday






          • 1




            In particular, is your property change notification the same i.e. MVVM Lite? Because if your call to RaisePropertyChanged is broken, or the parent class (MainViewModel) doesn't support property change notification, then it won't work.
            – Mark Feldman
            yesterday








          • 1




            In your property control you should be binding to Properties, not ChildViewModel.Properties. When you do a <ContentControl Content="{Binding ChildViewModel}" /> back in your main window xaml it already sets the DataContext for whatever is inside the ContentControl to the binding, i.e. ChildViewModel.
            – Mark Feldman
            yesterday













          up vote
          1
          down vote



          accepted







          up vote
          1
          down vote



          accepted






          In general you solve this with ContentControls and DataTemplates. Let's say you have a MainViewModel and you want to be able to display a child view model, so you start by exposing a property with property change notification, i.e. something like this:



              private object _MyChild;
          public object MyChild
          {
          get { return this._MyChild; }
          set
          {
          if (this._MyChild != value)
          {
          this._MyChild = value;
          RaisePropertyChanged(() => this.MyChild);
          }
          }
          }


          Over in the XAML for your main window you create a content control and bind it to this property:



          <ContentControl Content="{Binding MyChild}" />


          Finally in your resources block you create a DataTemplate for each child view model that you might assign to this property:



          <DataTemplate DataType="{x:Type local:ChildViewModel}">
          <local:ChildViewControl />
          </DataTemplate>


          <DataTemplate DataType="{x:Type local:ChildViewModel2}">
          <local:ChildViewControl2 />
          </DataTemplate>

          ... etc...


          Ordinarily this control won't be visible, but as soon as you assign an appropriate view model to the property it will automatically populate based on what you've specified in your data templates:



          this.MyChild = new ChildViewModel(); // <-- child control gets created and appears


          In practice your property wouldn't be of type object, you usually have some base class that all your child view models are derived from, but you get the idea.



          There are other ways to do this (e.g. DataTriggers) but DataTemplates are what you usually use for cases such as what you've described.



          UPDATE: Here's some fully working code, imagine your MainViewModel has a property for a child view model and a couple of button handlers to set and clear the child:



          public class MainViewModel : ViewModelBase
          {
          // Child property

          private ChildViewModel _Child;
          public ChildViewModel Child
          {
          get { return this._Child; }
          set
          {
          if (this._Child != value)
          {
          this._Child = value;
          RaisePropertyChanged(() => this.Child);
          }
          }
          }

          // Set child

          private ICommand _SetChildCommand;
          public ICommand SetChildCommand => this._SetChildCommand ?? (this._SetChildCommand = new RelayCommand(OnSetChild));

          private void OnSetChild()
          {
          this.Child = new ChildViewModel();
          }

          // Clear child

          private ICommand _ClearChildCommand;
          public ICommand ClearChildCommand => this._ClearChildCommand ?? (this._ClearChildCommand = new RelayCommand(OnClearChild));

          private void OnClearChild()
          {
          this.Child = null;
          }

          }

          public class ChildViewModel : ViewModelBase
          {
          public string Text => "I am child type 1!";
          }


          Then in your XAML all you need to do is this:



          <StackPanel Orientation="Horizontal" VerticalAlignment="Top" >
          <Button Content="Set Child" Command="{Binding SetChildCommand}" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="5" />
          <Button Content="Clear Child" Command="{Binding ClearChildCommand}" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="5" />


          <ContentControl Content="{Binding Child}">
          <ContentControl.Resources>
          <DataTemplate DataType="{x:Type local:ChildViewModel}">
          <TextBlock Text="{Binding Text}" Foreground="Yellow" Background="Blue" HorizontalAlignment="Left" VerticalAlignment="Center" />
          </DataTemplate>
          </ContentControl.Resources>
          </ContentControl>

          </StackPanel>


          Initially you'll only see the two buttons by themselves, but clicking on "Set Child" will cause the OnSetChild handler to get called, which will create a new instance of ChildViewModel and assign it to the property. Because of the DataTemplate the ContentControl will be automatically populated:



          enter image description here



          Likewise, clicking the "Clear child" button will clear the property and the yellow/blue text will disappear. (I'm using a TextBlock here but obviously you can use anything you want, including your own custom controls).






          share|improve this answer














          In general you solve this with ContentControls and DataTemplates. Let's say you have a MainViewModel and you want to be able to display a child view model, so you start by exposing a property with property change notification, i.e. something like this:



              private object _MyChild;
          public object MyChild
          {
          get { return this._MyChild; }
          set
          {
          if (this._MyChild != value)
          {
          this._MyChild = value;
          RaisePropertyChanged(() => this.MyChild);
          }
          }
          }


          Over in the XAML for your main window you create a content control and bind it to this property:



          <ContentControl Content="{Binding MyChild}" />


          Finally in your resources block you create a DataTemplate for each child view model that you might assign to this property:



          <DataTemplate DataType="{x:Type local:ChildViewModel}">
          <local:ChildViewControl />
          </DataTemplate>


          <DataTemplate DataType="{x:Type local:ChildViewModel2}">
          <local:ChildViewControl2 />
          </DataTemplate>

          ... etc...


          Ordinarily this control won't be visible, but as soon as you assign an appropriate view model to the property it will automatically populate based on what you've specified in your data templates:



          this.MyChild = new ChildViewModel(); // <-- child control gets created and appears


          In practice your property wouldn't be of type object, you usually have some base class that all your child view models are derived from, but you get the idea.



          There are other ways to do this (e.g. DataTriggers) but DataTemplates are what you usually use for cases such as what you've described.



          UPDATE: Here's some fully working code, imagine your MainViewModel has a property for a child view model and a couple of button handlers to set and clear the child:



          public class MainViewModel : ViewModelBase
          {
          // Child property

          private ChildViewModel _Child;
          public ChildViewModel Child
          {
          get { return this._Child; }
          set
          {
          if (this._Child != value)
          {
          this._Child = value;
          RaisePropertyChanged(() => this.Child);
          }
          }
          }

          // Set child

          private ICommand _SetChildCommand;
          public ICommand SetChildCommand => this._SetChildCommand ?? (this._SetChildCommand = new RelayCommand(OnSetChild));

          private void OnSetChild()
          {
          this.Child = new ChildViewModel();
          }

          // Clear child

          private ICommand _ClearChildCommand;
          public ICommand ClearChildCommand => this._ClearChildCommand ?? (this._ClearChildCommand = new RelayCommand(OnClearChild));

          private void OnClearChild()
          {
          this.Child = null;
          }

          }

          public class ChildViewModel : ViewModelBase
          {
          public string Text => "I am child type 1!";
          }


          Then in your XAML all you need to do is this:



          <StackPanel Orientation="Horizontal" VerticalAlignment="Top" >
          <Button Content="Set Child" Command="{Binding SetChildCommand}" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="5" />
          <Button Content="Clear Child" Command="{Binding ClearChildCommand}" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="5" />


          <ContentControl Content="{Binding Child}">
          <ContentControl.Resources>
          <DataTemplate DataType="{x:Type local:ChildViewModel}">
          <TextBlock Text="{Binding Text}" Foreground="Yellow" Background="Blue" HorizontalAlignment="Left" VerticalAlignment="Center" />
          </DataTemplate>
          </ContentControl.Resources>
          </ContentControl>

          </StackPanel>


          Initially you'll only see the two buttons by themselves, but clicking on "Set Child" will cause the OnSetChild handler to get called, which will create a new instance of ChildViewModel and assign it to the property. Because of the DataTemplate the ContentControl will be automatically populated:



          enter image description here



          Likewise, clicking the "Clear child" button will clear the property and the yellow/blue text will disappear. (I'm using a TextBlock here but obviously you can use anything you want, including your own custom controls).







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited yesterday

























          answered 2 days ago









          Mark Feldman

          7,86911638




          7,86911638












          • Thank you, it helps me to solve some of my problems but I still couldn't manage with dynamic user-control change ` public object _model; public object _ childView ` I couldn't figure it out how the change in the model, updates the current model-control (destroy and recreate)
            – Guray Golcuk
            2 days ago








          • 1




            I don't really know how to describe it more clearly than that....if you bind a ContentControl to your data, and use a DataTemplate for your view model data type, the content of the DataTemplate will appear as a child of the ContentControl. Set the property to null and it'll be destroyed. If you still can't get it to work then post some code that uses ContentControl and DataTemplate and I'll tell you what you're doing wrong.
            – Mark Feldman
            yesterday






          • 1




            So when you put a breakpoint in OnSetChild it gets hit when you press the button? Have you made any other changes to the code at all?
            – Mark Feldman
            yesterday






          • 1




            In particular, is your property change notification the same i.e. MVVM Lite? Because if your call to RaisePropertyChanged is broken, or the parent class (MainViewModel) doesn't support property change notification, then it won't work.
            – Mark Feldman
            yesterday








          • 1




            In your property control you should be binding to Properties, not ChildViewModel.Properties. When you do a <ContentControl Content="{Binding ChildViewModel}" /> back in your main window xaml it already sets the DataContext for whatever is inside the ContentControl to the binding, i.e. ChildViewModel.
            – Mark Feldman
            yesterday


















          • Thank you, it helps me to solve some of my problems but I still couldn't manage with dynamic user-control change ` public object _model; public object _ childView ` I couldn't figure it out how the change in the model, updates the current model-control (destroy and recreate)
            – Guray Golcuk
            2 days ago








          • 1




            I don't really know how to describe it more clearly than that....if you bind a ContentControl to your data, and use a DataTemplate for your view model data type, the content of the DataTemplate will appear as a child of the ContentControl. Set the property to null and it'll be destroyed. If you still can't get it to work then post some code that uses ContentControl and DataTemplate and I'll tell you what you're doing wrong.
            – Mark Feldman
            yesterday






          • 1




            So when you put a breakpoint in OnSetChild it gets hit when you press the button? Have you made any other changes to the code at all?
            – Mark Feldman
            yesterday






          • 1




            In particular, is your property change notification the same i.e. MVVM Lite? Because if your call to RaisePropertyChanged is broken, or the parent class (MainViewModel) doesn't support property change notification, then it won't work.
            – Mark Feldman
            yesterday








          • 1




            In your property control you should be binding to Properties, not ChildViewModel.Properties. When you do a <ContentControl Content="{Binding ChildViewModel}" /> back in your main window xaml it already sets the DataContext for whatever is inside the ContentControl to the binding, i.e. ChildViewModel.
            – Mark Feldman
            yesterday
















          Thank you, it helps me to solve some of my problems but I still couldn't manage with dynamic user-control change ` public object _model; public object _ childView ` I couldn't figure it out how the change in the model, updates the current model-control (destroy and recreate)
          – Guray Golcuk
          2 days ago






          Thank you, it helps me to solve some of my problems but I still couldn't manage with dynamic user-control change ` public object _model; public object _ childView ` I couldn't figure it out how the change in the model, updates the current model-control (destroy and recreate)
          – Guray Golcuk
          2 days ago






          1




          1




          I don't really know how to describe it more clearly than that....if you bind a ContentControl to your data, and use a DataTemplate for your view model data type, the content of the DataTemplate will appear as a child of the ContentControl. Set the property to null and it'll be destroyed. If you still can't get it to work then post some code that uses ContentControl and DataTemplate and I'll tell you what you're doing wrong.
          – Mark Feldman
          yesterday




          I don't really know how to describe it more clearly than that....if you bind a ContentControl to your data, and use a DataTemplate for your view model data type, the content of the DataTemplate will appear as a child of the ContentControl. Set the property to null and it'll be destroyed. If you still can't get it to work then post some code that uses ContentControl and DataTemplate and I'll tell you what you're doing wrong.
          – Mark Feldman
          yesterday




          1




          1




          So when you put a breakpoint in OnSetChild it gets hit when you press the button? Have you made any other changes to the code at all?
          – Mark Feldman
          yesterday




          So when you put a breakpoint in OnSetChild it gets hit when you press the button? Have you made any other changes to the code at all?
          – Mark Feldman
          yesterday




          1




          1




          In particular, is your property change notification the same i.e. MVVM Lite? Because if your call to RaisePropertyChanged is broken, or the parent class (MainViewModel) doesn't support property change notification, then it won't work.
          – Mark Feldman
          yesterday






          In particular, is your property change notification the same i.e. MVVM Lite? Because if your call to RaisePropertyChanged is broken, or the parent class (MainViewModel) doesn't support property change notification, then it won't work.
          – Mark Feldman
          yesterday






          1




          1




          In your property control you should be binding to Properties, not ChildViewModel.Properties. When you do a <ContentControl Content="{Binding ChildViewModel}" /> back in your main window xaml it already sets the DataContext for whatever is inside the ContentControl to the binding, i.e. ChildViewModel.
          – Mark Feldman
          yesterday




          In your property control you should be binding to Properties, not ChildViewModel.Properties. When you do a <ContentControl Content="{Binding ChildViewModel}" /> back in your main window xaml it already sets the DataContext for whatever is inside the ContentControl to the binding, i.e. ChildViewModel.
          – Mark Feldman
          yesterday


















           

          draft saved


          draft discarded



















































           


          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53187784%2fwpf-how-to-destroy-and-recreate-usercontrol-based-on-changes-in-other-bindin%23new-answer', 'question_page');
          }
          );

          Post as a guest




















































































          Popular posts from this blog

          Guess what letter conforming each word

          Port of Spain

          Run scheduled task as local user group (not BUILTIN)