How to bind user control property to other property? - c#

I have the following user control:
The Xaml:
<UserControl x:Class="ScreenRecorder.TimePicker"
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"
mc:Ignorable="d" Height="27" Width="176">
<Grid>
<StackPanel Orientation="Horizontal">
<TextBox Width="150" Height="25" Text="{Binding Time}" HorizontalAlignment="Left" VerticalAlignment="Top"/>
<StackPanel Orientation="Vertical">
<Button Width="25" Height="12.5" HorizontalAlignment="Left" VerticalAlignment="Top" Click="btnKeyUp_Clicked">
<Image Source="up.png" Height="10" Width="10" VerticalAlignment="Top"/>
</Button>
<Button Width="25" Height="12.5" HorizontalAlignment="Left" VerticalAlignment="Top" Click="btnKeyDown_Clicked">
<Image Source="down.png" Height="10" Width="10" VerticalAlignment="Top"/>
</Button>
</StackPanel>
</StackPanel>
</Grid>
The Code:
public partial class TimePicker : UserControl, INotifyPropertyChanged
{
public TimePicker()
{
InitializeComponent();
this.DataContext = this;
//Time = m_time;
}
public static DependencyProperty TimeProperty = DependencyProperty.Register(
"Time", typeof(string), typeof(TimePicker));
//private string m_time = DateTime.Now.ToString();
public string Time
{
get { return (string)GetValue(TimeProperty); }
set
{
SetValue(TimeProperty, value);
NotifyPropertyChanged("Time");
}
}
private void btnKeyUp_Clicked(object sender, RoutedEventArgs e)
{
DateTime curTime = Convert.ToDateTime(Time);
curTime += new TimeSpan(0, 0, 1);
Time = curTime.ToString();
}
private void btnKeyDown_Clicked(object sender, RoutedEventArgs e)
{
DateTime curTime = Convert.ToDateTime(Time);
curTime -= new TimeSpan(0, 0, 1);
Time = curTime.ToString();
}
#region INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String propertyName = "")
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
}
And I have another user control that uses this user control as follow:
<StackPanel>
<Label Content="Begin Record Time" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="5"/>
<local:TimePicker Time="{Binding StartRecordTime}"/>
</StackPanel>
StartRecordTime looks like this:
public string StartRecordTime
{
get { return m_startRecord; }
set
{
m_startRecord = value;
NotifyPropertyChanged("StartRecordTime");
}
}
I want to change the StartRecordTime according to the Time Property and vice versa, but only the Time property is changing.
Thank you.

Try this:
<local:TimePicker Time="{Binding Path=StartRecordTime, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>

Your binding won't work as you've set the DataContext of TimePicker to TimePicker itself. You'll notice a binding error in the Output window:
BindingExpression path error: 'StartRecordTime' property not found on 'object' ''TimePicker' (Name='')'. BindingExpression:Path=StartRecordTime; DataItem='TimePicker' (Name=''); target element is 'TimePicker' (Name=''); target property is 'Time' (type 'String')
I'd suggest to have a more 'sane' experience you remove DataContext = this from the TimePicker constructor and set the Grid's DataContext to the TimePicker by Element Name. Add a name attribute to the UserControl element:
<UserControl x:Name="Root" ...
And set the DataContext of the Grid:
<Grid DataContext="{Binding ElementName=Root}">
This will be inherited by all child elements. You will also need to change your binding to TwoWay, either explicitly:
<local:TimePicker Time="{Binding Path=StartRecordTime, Mode=TwoWay}" />
Or by setting this as the default in the DependencyProperty registration:
public static readonly DependencyProperty TimeProperty = DependencyProperty.Register(
"Time", typeof(string), typeof(TimePicker),
new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
I'd also note that there's no reason for TimePicker to implement INotifyPropertyChanged. I suggest you remove this.

Related

WinUI 3 How to Bind Command to ViewModel property when using a DataTemplate?

I am using a Grid called MainGrid to position an ItemsRepeater whose ItemsSource is bound to an ObservableCollection within my ViewModel.
<muxc:ItemsRepeater
ItemsSource="{Binding Path=Molts}"
Layout="{StaticResource VerticalStackLayout}"
ItemTemplate="{StaticResource MoltTemplate}">
</muxc:ItemsRepeater>
I have created a DataTemplate
<DataTemplate x:Key="MoltTemplate">
<StackPanel Orientation="Horizontal">
<TextBlock x:Name="text" Text="{Binding ID}"></TextBlock>
<Button Command="{Binding DisplayAvailAIsCommand}" CommandParameter="{Binding ElementName=text, Path=Text}">Add</Button>
</StackPanel>
</DataTemplate>
which has a TextBox and Button. I want the Button to fire a command in my ViewModel but items within the ItemsRepeater have their DataContext set to their Model class and not the ViewModel. I found this post which states that I can change the Command of my Button to set the DataContext to my ViewModel by setting ElementName to a UI element that has as its DataContext the ViewModel
<Button Command="{Binding DataContext.DisplayAvailAIsCommand, ElementName=MainGrid}" CommandParameter="{Binding ElementName=text, Path=Text}">Add</Button>
The constructor of my window sets the DataContext of the MainGrid like this
public MainWindow()
{
this.InitializeComponent();
MainGrid.DataContext = new MoltViewModel();
}
However, this does not work and the command does not fire. What am I doing wrong?
You could create an attached property that sets the DataContext of the Button to a parent element of a specific type such as for example ItemsRepeater:
public static class AncestorSource
{
public static readonly DependencyProperty AncestorTypeProperty =
DependencyProperty.RegisterAttached(
"AncestorType",
typeof(Type),
typeof(AncestorSource),
new PropertyMetadata(default(Type), OnAncestorTypeChanged)
);
public static void SetAncestorType(FrameworkElement element, Type value) =>
element.SetValue(AncestorTypeProperty, value);
public static Type GetAncestorType(FrameworkElement element) =>
(Type)element.GetValue(AncestorTypeProperty);
private static void OnAncestorTypeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
FrameworkElement target = (FrameworkElement)d;
if (target.IsLoaded)
SetDataContext(target);
else
target.Loaded += OnTargetLoaded;
}
private static void OnTargetLoaded(object sender, RoutedEventArgs e)
{
FrameworkElement target = (FrameworkElement)sender;
target.Loaded -= OnTargetLoaded;
SetDataContext(target);
}
private static void SetDataContext(FrameworkElement target)
{
Type ancestorType = GetAncestorType(target);
if (ancestorType != null)
target.DataContext = FindParent(target, ancestorType);
}
private static object FindParent(DependencyObject dependencyObject, Type ancestorType)
{
DependencyObject parent = VisualTreeHelper.GetParent(dependencyObject);
if (parent == null)
return null;
if (ancestorType.IsAssignableFrom(parent.GetType()))
return parent;
return FindParent(parent, ancestorType);
}
}
Usage:
<DataTemplate x:Key="MoltTemplate">
<StackPanel Orientation="Horizontal">
<TextBlock x:Name="text" Text="{Binding ID}"></TextBlock>
<Button local:AncestorSource.AncestorType="muxc:ItemsRepeater"
Command="{Binding DataContext.DisplayAvailAIsCommand}"
CommandParameter="{Binding ElementName=text, Path=Text}">Add</Button>
</StackPanel>
</DataTemplate>
Please refer to this blog post for more information.

Binding properties of User Control in Windows Phone Application

In a LongListSelector, I have multiple items shown, according to the following DataTemplate :
<TextBlock Text="{Binding Subject}" TextWrapping="Wrap" Style="{StaticResource PhoneTextExtraLargeStyle}" />
<StackPanel Orientation="Horizontal">
<TextBlock Text="Last modified :" Margin="15, 0, 5, 0" Foreground="LightGray" Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock Text="{Binding LastModified}" Foreground="#989696" Style="{StaticResource PhoneTextNormalStyle}"/>
</StackPanel>
At this point, everything works fine, the MVVM and bindings are OK.
I wanted to move this XAML into an UserControl and bind those properties from it. And, I have thought to proceed in this way :
<UserControl x:Class="..."
xmlns=" ... "
Foreground="{StaticResource PhoneForegroundBrush}"
d:DesignHeight="100" d:DesignWidth="480">
<StackPanel x:Name="LayoutRoot" Background="Transparent">
<TextBlock x:Name="TitleTextBlock" Style="{StaticResource PhoneTextExtraLargeStyle}" />
<StackPanel Orientation="Horizontal">
<TextBlock Text="Last modified :" Margin="15, 0, 5, 0" Foreground="LightGray" Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock x:Name="LastModifiedDateTextBlock" Foreground="#989696" Style="{StaticResource PhoneTextNormalStyle}"/>
</StackPanel>
</StackPanel>
</UserControl>
And this is the C# class :
public partial class LongListSelectorItemControl
{
private DateTime _lastModifiedDate;
public string Title
{
get
{
return TitleTextBlock.Text;
}
set
{
TitleTextBlock.Text = value;
}
}
public DateTime LastModifiedDate
{
get
{
return _lastModifiedDate;
}
set
{
LastModifiedDateTextBlock.Text = value.ToString(CultureInfo.InvariantCulture);
_lastModifiedDate = value;
}
}
public LongListSelectorItemControl()
{
InitializeComponent();
_lastModifiedDate = new DateTime();
}
}
I have thought to use the user control in XAML in this way :
<userControls:LongListSelectorItemControl Title="{Binding Subject}" LastModifiedDate="{Binding LastModified}"/>
But something went wrong and I can't figure out what. I guess it has to do something with an incorrect binding... because in my application, a page is loaded with this XAML I presented in this issue and the app doesn't crash. Then the user has to navigate to another page, where some data is added and the ViewModel will have some data to show, so when it returns to the main page, this time, it simply crashes... (gets me to Application_UnhandledException method in App.xaml.cs to break the debugger.
Additional research
I've managed to track down the exception and it seems...
MS.Internal.WrappedException: Object of type 'System.Windows.Data.Binding' cannot be converted to type 'System.String'. ---> System.ArgumentException: Object of type 'System.Windows.Data.Binding' cannot be converted to type 'System.String'
I am still confused on how to fix this...
Any suggestions are welcome to aid me into figuring out what's wrong. Thanks!
To be able to bind to a property, it need to be a dependency property. Here is how the title property need to be modified:
public partial class LongListSelectorItemControl
{
public static readonly DependencyProperty TitleProperty =
DependencyProperty.Register("Title", typeof(string), typeof(LongListSelectorItemControl), new PropertyMetadata(default(string), TitlePropertyChanged));
private static void TitlePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
LongListSelectorItemControl myControl=d as LongListSelectorItemControl;
myControl.TitleTextBlock.Text = e.NewValue as string;
}
public string Title
{
get { return (string) GetValue(TitleProperty); }
set { SetValue(TitleProperty, value); }
}
....
}
You will need to do the same thing with the LastModifiedDate property.

Dynamic user control change - WPF

I'm developing an app in WPF and I need to change in runtime a content of a ContentControl depending than the user selected on ComboBox.
I have two UserControls and at my combo exists two itens, corresponding each one each.
First usercontrol:
<UserControl x:Class="Validator.RespView"
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"
mc:Ignorable="d"
d:DesignHeight="167" d:DesignWidth="366" Name="Resp">
<Grid>
<CheckBox Content="CheckBox" Height="16" HorizontalAlignment="Left" Margin="12,12,0,0" Name="checkBox1" VerticalAlignment="Top" />
<ListBox Height="112" HorizontalAlignment="Left" Margin="12,43,0,0" Name="listBox1" VerticalAlignment="Top" Width="168" />
<Calendar Height="170" HorizontalAlignment="Left" Margin="186,0,0,0" Name="calendar1" VerticalAlignment="Top" Width="180" />
</Grid>
Second usercontrol:
<UserControl x:Class="Validator.DownloadView"
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"
mc:Ignorable="d"
d:DesignHeight="76" d:DesignWidth="354" Name="Download">
<Grid>
<Label Content="States" Height="28" HorizontalAlignment="Left" Margin="12,12,0,0" Name="label1" VerticalAlignment="Top" />
<ComboBox Height="23" HorizontalAlignment="Left" Margin="12,35,0,0" Name="comboBox1" VerticalAlignment="Top" Width="120" />
<RadioButton Content="Last 48 hs" Height="16" HorizontalAlignment="Left" Margin="230,42,0,0" Name="rdbLast48" VerticalAlignment="Top" />
<Label Content="Kind:" Height="28" HorizontalAlignment="Left" Margin="164,12,0,0" Name="label2" VerticalAlignment="Top" />
<RadioButton Content="General" Height="16" HorizontalAlignment="Left" Margin="165,42,0,0" Name="rdbGeral" VerticalAlignment="Top" />
</Grid>
At MainWindowView.xaml
<Window x:Class="Validator.MainWindowView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:du="clr-namespace:Validator.Download"
xmlns:resp="clr-namespace:Validator.Resp"
Title="Validator" Height="452" Width="668"
WindowStartupLocation="CenterScreen" ResizeMode="NoResize">
<Window.Resources>
<DataTemplate DataType="{x:Type du:DownloadViewModel}">
<du:DownloadView/>
</DataTemplate>
<DataTemplate DataType="{x:Type resp:RespViewModel}">
<resp:RespView/>
</DataTemplate>
</Window.Resources>
<Grid>
<ComboBox ItemsSource="{Binding Path=PagesName}"
SelectedValue="{Binding Path=CurrentPageName}"
HorizontalAlignment="Left" Margin="251,93,0,0"
Name="cmbType"
Width="187" VerticalAlignment="Top" Height="22"
SelectionChanged="cmbType_SelectionChanged_1" />
<ContentControl Content="{Binding CurrentPageViewModel}" Height="171" HorizontalAlignment="Left" Margin="251,121,0,0" Name="contentControl1" VerticalAlignment="Top" Width="383" />
</Grid>
</Window>
I assigned to the DataContext of the MainView, the viewmodel below:
public class MainWindowViewModel : ObservableObject
{
#region Fields
private ICommand _changePageCommand;
private ViewModelBase _currentPageViewModel;
private ObservableCollection<ViewModelBase> _pagesViewModel = new ObservableCollection<ViewModelBase>();
private readonly ObservableCollection<string> _pagesName = new ObservableCollection<string>();
private string _currentPageName = "";
#endregion
public MainWindowViewModel()
{
this.LoadUserControls();
_pagesName.Add("Download");
_pagesName.Add("Resp");
}
private void LoadUserControls()
{
Type type = this.GetType();
Assembly assembly = type.Assembly;
UserControl reso = (UserControl)assembly.CreateInstance("Validator.RespView");
UserControl download = (UserControl)assembly.CreateInstance("Validator.DownloadView");
_pagesViewModel.Add(new DownloadViewModel());
_pagesViewModel.Add(new RespViewModel());
}
#region Properties / Commands
public ICommand ChangePageCommand
{
get
{
if (_changePageCommand == null)
{
_changePageCommand = new RelayCommand(
p => ChangeViewModel((IPageViewModel)p),
p => p is IPageViewModel);
}
return _changePageCommand;
}
}
public ObservableCollection<string> PagesName
{
get { return _pagesName; }
}
public string CurrentPageName
{
get
{
return _currentPageName;
}
set
{
if (_currentPageName != value)
{
_currentPageName = value;
OnPropertyChanged("CurrentPageName");
}
}
}
public ViewModelBase CurrentPageViewModel
{
get
{
return _currentPageViewModel;
}
set
{
if (_currentPageViewModel != value)
{
_currentPageViewModel = value;
OnPropertyChanged("CurrentPageViewModel");
}
}
}
#endregion
#region Methods
private void ChangeViewModel(IPageViewModel viewModel)
{
int indexCurrentView = _pagesViewModel.IndexOf(CurrentPageViewModel);
indexCurrentView = (indexCurrentView == (_pagesViewModel.Count - 1)) ? 0 : indexCurrentView + 1;
CurrentPageViewModel = _pagesViewModel[indexCurrentView];
}
#endregion
}
On MainWindowView.xaml.cs, I wrote this event to do the effective change:
private void cmbType_SelectionChanged_1(object sender, SelectionChangedEventArgs e)
{
MainWindowViewModel element = this.DataContext as MainWindowViewModel;
if (element != null)
{
ICommand command = element.ChangePageCommand;
command.Execute(null);
}
}
The app run ok and I inspected the application with WPFInspector and saw that the view changes when the combobox is changed internally, but the ContentControl still empty visually..
Sorry about the amount of code that I posted and my miss of knowledge but I'm working with this a long time and can't solve this problem.
Thanks
Issues:
Firstly don't ever create View related stuff in the ViewModel (UserControl). This is no longer MVVM when you do that.
Derive ViewModels from ViewModelBase and not ObservableObject unless you have a compelling reason to not use ViewModelBase when using MVVMLight. Keep ObservableObject inheritence for Models. Serves as a nice separation between VM's and M's
Next you do not need to make everything an ObservableCollection<T> like your _pagesViewModel. You do not have that bound to anything in your View's so it's just a waste. Just keep that as a private List or array. Check what a type actually does in difference to a similar other one.
Not sure about this one, maybe you pulled this code snippet as a demo, but do not use margins to separate items in a Grid. Your Layout is essentially just 1 Grid cell and the margins have the items not overlap. If you're not aware of that issue, Check into WPF Layout Articles.
Please don't forget principles of OOP, Encapsulation and sorts when writing a UI app. When having Properties like CurrentPageViewModel which you don't intend the View to switch make the property setter private to enforce that.
Don't resort to code-behind in the View too soon. Firstly check if it's only a View related concern before doing so. Am talking about your ComboBox SelectionChanged event handler. Your purpose of that in this demo is to switch the Bound ViewModel which is held in the VM. Hence it's not something that the View is solely responsible for. Thus look for a VM involved approach.
Solution:
You can get a working example of your code with the fixes for above from Here and try it out yourself.
Points 1 -> 5 are just basic straightforward changes.
For 6, I've created a SelectedVMIndex property in the MainViewModel which is bound to the SelectedIndex of the ComboBox. Thus when the selected index flips, the property setter after updating itself updates the CurrentPageViewModel as well such as
public int SelectedVMIndex {
get {
return _selectedVMIndex;
}
set {
if (_selectedVMIndex == value) {
return;
}
_selectedVMIndex = value;
RaisePropertyChanged(() => SelectedVMIndex);
CurrentPageViewModel = _pagesViewModel[_selectedVMIndex];
}
}

TextBox in UserControl, can't edit Text dependency property from code behind

My UserControl contains a TextBox and a Button. The TextBox's Text is correctly populated by a dependency property called X.
My Goal:
Change the value of X (e.g. Text of the TextBox) when I press the Button.
I have defined the UserControl as follows:
<StackPanel Orientation="Horizontal" >
<TextBox Name="Xbox" Text="{Binding Path=X}" Width="50"/>
<Button Content="Current" Click="InsertCurrentBtnClick" />
</StackPanel>
With codebehind:
public double X
{
get { return (double)GetValue(XProperty); }
set { SetValue(XProperty, value); }
}
public static readonly DependencyProperty XProperty =
DependencyProperty.Register("X", typeof(double), typeof(MyUserControl), new PropertyMetadata(0.0));
private void InsertCurrentBtnClick(object sender, RoutedEventArgs e)
{
X = 0.7;
//BindingOperations.GetBindingExpression(this, XProperty).UpdateTarget();
//BindingOperations.GetBindingExpression(Xbox, TextBox.TextProperty).UpdateTarget();
//BindingOperations.GetBindingExpression(Xbox, XProperty).UpdateTarget();
//Xbox.GetBindingExpression(TextBox.TextProperty).UpdateTarget();
//GetBindingExpression(XProperty).UpdateTarget();
}
I have tried several things - one at a time - (see below X=0.7;) to force the update to the TextBox Text but nothing has helped so far.
Thanks in advance.
I'd write it in this way:
public double X
{
get { return (double)GetValue(XProperty); }
set { SetValue(XProperty, value); }
}
public static readonly DependencyProperty XProperty =
DependencyProperty.Register("X", typeof(double), typeof(MainPage), new PropertyMetadata(new PropertyChangedCallback(Callback)));
public static void Callback(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
(o as MainPage).Xbox.Text = e.NewValue.ToString();
}
private void InsertCurrentBtnClick(object sender, RoutedEventArgs e)
{
X = 0.7;
}
And the xaml code:
<StackPanel Orientation="Horizontal" >
<TextBox Name="Xbox" Width="50"/>
<Button Content="Current" Click="InsertCurrentBtnClick" />
</StackPanel>
You need to set the DataContext for you Control. As I see X defined in your control, you need to do this :
public MyUserControl()
{
InitializeComponent();
// add this line
this.DataContext = this;
}
Although, you can bind it as well, just change the xaml:
<UserControl x:Class="SilverlightApplication1.MainPage"
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"
mc:Ignorable="d"
Name="myWidnow"
d:DesignHeight="300" d:DesignWidth="400">
<Grid x:Name="LayoutRoot" Background="White">
<StackPanel Orientation="Horizontal" >
<TextBox Name="Xbox" Width="50" Text="{Binding ElementName=myWidnow, Path=X}" />
<Button Content="Current" Click="InsertCurrentBtnClick" />
</StackPanel>
</Grid>
Notice that I've added the Name proeprty to the UserControl.
In this case, you don't have to change anything in the code behid.

Is there some way I can use assign a value in MainPage and bind it in the child window

I've a Silverlight application wherein I've a MainPage in which I need to assign a variable Name in the childwindow and assign it without using the object of the child. I need to bind thise value to a textbox in the Childwindow through XAML. How can it be done?
So far what I've done is using a dependancy property in the childwindow:
nameProp = DependencyProperty.Register("strName", typeof(string), typeof(TestWindow), new PropertyMetadata(null, new PropertyChangedCallback(OnNameChange)));
static TestWindow()
{
nameProp = DependencyProperty.Register("strName", typeof(string), typeof(TestWindow), new PropertyMetadata(null, new PropertyChangedCallback(OnNameChange)));
}
private static void OnNameChange(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
d.SetValue(nameProp, e.NewValue);
}
public string strName
{
get {
return (string)GetValue(nameProp);
}
set {
SetValue(nameProp, value);
}
}
and in TestWindow XAML i try to bind it:
<TextBox Text="{Binding Path=strName}" Height="23" HorizontalAlignment="Left" Margin="126,84,0,0" Name="txtName" VerticalAlignment="Top" Width="120"/>
How can I set the value for this dp from MainPage. Or is there any better alternative?
One way will be:
Make those variables public properties of your MainPage.
Assign the mainPage to be your child window DataContext.
Bind to those properties via XAML in your childWindow.
i am hoping that this will helps you....what you are trying to achieve....
ChildWindow Xaml file:
<controls:ChildWindow x:Class="ParentToChildWindow.ChildWindowControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls"
Width="400" Height="300"
Title="Pass Data from Parent to ChildWindow">
<Grid x:Name="LayoutRoot" Margin="2">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Orientation="Vertical">
<TextBlock x:Name="txtValue" />
<TextBlock x:Name="txtName"/>
</StackPanel>
<Button x:Name="CancelButton" Content="Cancel" Click="CancelButton_Click" Width="75"
Height="23" HorizontalAlignment="Right" Margin="0,12,0,0" Grid.Row="1" />
<Button x:Name="OKButton" Content="OK" Click="OKButton_Click" Width="75" Height="23"
HorizontalAlignment="Right" Margin="0,12,79,0" Grid.Row="1" />
</Grid>
</controls:ChildWindow>
ChildWindow CS file:
namespace ParentToChildWindow
{
using System.Windows;
using System.Windows.Controls;
public partial class ChildWindowControl : ChildWindow
{
public int Value { get; set; }
public string Name { get; set; }
public ChildWindowControl()
{
InitializeComponent();
}
private void OKButton_Click(object sender, RoutedEventArgs e)
{
this.txtValue.Text = this.Value.ToString();
this.txtName.Text = this.Name;
}
private void CancelButton_Click(object sender, RoutedEventArgs e)
{
this.DialogResult = false;
}
}
}
Parent CS File: I have added a button to parent XAML and added a click event
private void HandleButtonClickEvent(object sender, RoutedEventArgs e)
{
ChildWindowControl childControl = new ChildWindowControl();
childControl.Value = 10;
childControl.Name = "Data From Parent XAML to ChildWindow";
childControl.Show();
}
Pass the value in the constructor of theChildWindow
For this the place where we create the new instance of ChildWindow, we need to pass the required values to the Constructor. But remember, there must be a matching constructor already present in the ChildWindow control.
public ChildWindowControl(int value, string name)
{
InitializeComponent();
this.Value = value;
this.Name = name;
}
That is all that is required to pass the data from Parent XAML to ChildWindow

Categories