I have 2 UserControl, where the Usercontrol should get the Updated Data from MainWindow
<Window x:Class="BindingUserControl.MainWindow"
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:BindingUserControl.Pages"
xmlns:local1="clr-namespace:BindingUserControl"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<local1:CommonViewModel x:Key="ABC"/>
</Window.Resources>
<Grid>
<local:UserControl1 DataContext="{Binding Source={StaticResource ABC}}" Margin="0,0,520.6,264"/>
<TextBox Width ="100" Height="100" Text="{Binding CommonProperity}"/>
<Button Width="100" Height="100" RenderTransformOrigin="-1.85,1.404" Margin="139,208,554.6,112" Click="Button_Click"></Button>
</Grid>
UserControl
<UserControl x:Class="BindingUserControl.Pages.UserControl1"
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:BindingUserControl"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<UserControl.Resources>
<Local:CommonViewModel x:Key="ABC"/>
</UserControl.Resources>
<Grid DataContext="{Binding Source={StaticResource ABC}}" >
<TextBox Width="100" Height="100" Text="{Binding CommonProperity ,Mode=TwoWay}" />
</Grid>
Viewmodel
namespace BindingUserControl
{
class CommonViewModel: INotifyPropertyChanged
{
private string _Localtextdata;
public string CommonProperity
{
get { return _Localtextdata; }
set
{
_Localtextdata = value;
INotifyPropertyChanged("CommonProperity");
}
}
private void INotifyPropertyChanged(string ProperityName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(ProperityName));
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
}
There is no updated text in the usercontrol textbox when ever the Mainwindow textbox get any entry.
Where is my mistake?
You should only create one instance of CommonViewModel and let the UserControl inherit the DataContext from the window. Don't explicitly set the DataContext of the UserControl or any its child elements somewhere:
<Window x:Class="BindingUserControl.MainWindow"
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:BindingUserControl.Pages"
xmlns:local1="clr-namespace:BindingUserControl"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<!-- Set the DataContext property -->
<Window.DataContext>
<local1:CommonViewModel x:Key="ABC"/>
</Window.DataContext>
<Grid>
<local:UserControl1 Margin="0,0,520.6,264"/>
<TextBox Width ="100" Height="100" Text="{Binding CommonProperity}"/>
<Button Width="100" Height="100" RenderTransformOrigin="-1.85,1.404" Margin="139,208,554.6,112" Click="Button_Click"></Button>
</Grid>
</Window>
<UserControl x:Class="BindingUserControl.Pages.UserControl1"
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:BindingUserControl"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<TextBox Width="100" Height="100" Text="{Binding CommonProperity ,Mode=TwoWay}" />
</Grid>
</UserControl>
Related
MainWindow.xaml:
<Window x:Class="POGPOS.Views.MainWindow"
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:POGPOS.Views"
mc:Ignorable="d"
Loaded="StartApi"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Button Content="Open Window" Click="ButtonClicked" Height="25" HorizontalAlignment="Left"
Margin="379,264,0,0" Name="button1" VerticalAlignment="Top" Width="100" />
</Grid>
</Window>
MainWindow.xaml.cs
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void ButtonClicked(object sender, RoutedEventArgs e)
{
SubWindow subWindow = new SubWindow();
subWindow.Show();
}
}
SubWindow.xaml:
<Window x:Class="POGPOS.Views.Subwindow"
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:POGPOS.Views"
mc:Ignorable="d"
Name="Detail" Height="2400" Width="1765" AllowsTransparency ="True">
<Grid>
<Button Content="Open Window" Click="ButtonClicked" Height="25" HorizontalAlignment="Left"
Margin="379,264,0,0" Name="button1" VerticalAlignment="Top" Width="100" />
</Grid>
</Window>
SubWindow.xaml.cs
public partial class DetailView : Window
{
public DetailView() : base()
{
--------------------------------
}
}
But the error here is : InvalidOperationException: Window must be the root of the tree. Cannot add Window as a child of Visual.
I am new to WPF and I tried a simple dropdown menue with a list as ItemsSource. My ComboBox unfortunately stays empty while my list should be fine.
Can you guys help me out?
My XAML:
<Window x:Class="ProjectX.MainWindow"
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:vm="clr-namespace:ProjectX.ViewModel"
xmlns:local="clr-namespace:ProjectX"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800"
DataContext="{DynamicResource ViewModelMain}">
<Window.Resources>
<vm:ViewModelMain x:Key="ViewModelMain"/>
</Window.Resources>
<Grid>
<ComboBox ItemsSource="{Binding WaageListe}" DisplayMemberPath="{Binding Waage}" />
</Grid>
</Window>
And here is my ViewModel:
using ProjectX.Model;
using System.Collections.ObjectModel;
namespace ProjectX.ViewModel
{
public class ViewModelMain : ViewModelBase
{
public ObservableCollection<Waage> waageListe;
public ObservableCollection<Waage> WaageListe
{
get => waageListe;
set
{
RaisePropertyChanged("WaageListe");
}
}
public ViewModelMain()
{
WaageListe = new ObservableCollection<Waage>
{
new Waage {Name="Hamburg - 1"},
new Waage {Name="Hamburg - 2"},
new Waage {Name="Hamburg - 3"},
};
}
}
}
Use this:
<Window x:Class="ProjectX.MainWindow"
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:vm="clr-namespace:ProjectX.ViewModel"
xmlns:local="clr-namespace:ProjectX"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.DataContext>
<vm:ViewModelMain />
</Window.DataContext>
<Grid>
<ComboBox ItemsSource="{Binding WaageListe}" DisplayMemberPath="Name"/>
</Grid>
And:
using ProjectX.Model;
using System.Collections.ObjectModel;
namespace ProjectX.ViewModel
{
public class ViewModelMain : ViewModelBase
{
public ObservableCollection<Waage> WaageListe {get;} = new ObservableCollection<Waage>();
public ViewModelMain()
{
WaageListe.Add(new Waage {Name="Hamburg - 1"});
WaageListe.Add(new Waage {Name="Hamburg - 2"});
WaageListe.Add(new Waage {Name="Hamburg - 3"});
}
}
}
Set the DisplayMemberPath to "Name". You should also set the DataContext correctly:
<Window x:Class="ProjectX.MainWindow"
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:vm="clr-namespace:ProjectX.ViewModel"
xmlns:local="clr-namespace:ProjectX"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.DataContext>
<vm:ViewModelMain />
</Window.Resources>
<Grid>
<ComboBox ItemsSource="{Binding WaageListe}" DisplayMemberPath="Name" />
</Grid>
</Window>
"Name" is a public property of the Waage class.
You could also define an ItemTemplate:
<ComboBox ItemsSource="{Binding WaageListe}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
Waage is a type name but not a property name.
I have MainWindow.xaml that has ContentControl.
I have 4 UserControls that i created.
I want to change content of ContentControl in MainWindow.xaml when button pressed inside of my UserControl.
Here is my MainWindow.xaml:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ed="http://schemas.microsoft.com/expression/2010/drawing" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:KIOSK" mc:Ignorable="d" x:Class="KIOSK.MainWindow"
Title="MainWindow" Height="350" Width="525" WindowState="Maximized">
<ContentControl Name="contentMain">
<local:main_screen />
</ContentControl>
</Window>
Here my UserControls:
1)main_screen.xaml
<UserControl x:Class="KIOSK.main_screen"
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="300" d:DesignWidth="300">
<Grid Name="grid1" ShowGridLines="True">
<Button Margin="10" Background="#FFA4F200" Click="Button_Click"/>
</Grid>
</UserControl>
2) ClubRules.xaml
<UserControl x:Class="KIOSK.ClubRules"
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="300" d:DesignWidth="300" Background="White">
<Grid ShowGridLines="True" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" x:Name="grid1">
<Button Margin="0,15,0,15" Background="#FFFE0555" HorizontalAlignment="Center" Click="Button_Click" />
</Grid>
</UserControl>
Inside of main_creen.xaml.cs i wrote for button pressed:
ClubRules cr = new ClubRules();
MainWindow mw = new MainWindow();
mw.contentMain.Content = new ClubRules();
But its not working..
I want to change Content of ContentControl inside of UserControl when button pressed.
Use delegates and events for your scenario.
Publish an event main_screen.xaml.cs and Subscribe the event in MainWindow.xaml.cs
Publish the event
main_screen.xaml.cs
public partial class main_screen: UserControl
{
public Delegate del;
public main_screen()
{
InitializeComponent();
}
public void method1()
{
del.DynamicInvoke();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
method1();
}
}
Subscribe that event in MainWindow.xaml.cs
MainWindow.Xaml
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ed="http://schemas.microsoft.com/expression/2010/drawing" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:KIOSK" mc:Ignorable="d" x:Class="KIOSK.MainWindow"
Title="MainWindow" Height="350" Width="525" WindowState="Maximized">
<ContentControl Name="contentMain">
<local:main_screen x:Name="main_screen_obj" />
</ContentControl>
</Window>
MainWindow.xaml.cs
public partial class MainWindow : Window
{
public delegate void ValuePassDelegate();
public event ValuePassDelegate ValuePassEvent;
public MainWindow()
{
InitializeComponent();
ValuePassEvent += new ValuePassDelegate(method1);
main_screen_obj.del = ValuePassEvent;
}
public void method1()
{
contentMain.Content = new ClubRules();
}
}
You are creating a new MainWindow() instead of using the one that is being displayed. You should be assigning the ClubRules to the Content of the one that is being displayed.
One way to do that is by bringing the button from the UserControl to the MainWindow itself. Other way as suggested by #decoherence is by using the singleton pattern.
There could be more ways, but you basically need to use the same instance of the MainWindow that has been displayed.
EDIT: It seems like that I needed to change the height of RowDefinition. Thanks goes to Alvaro. However:
how do I reference different elements inside my usercontrol (change their properties), when I want to change them in MainWindow.xaml and MainWindow.xaml.cs?
I have two XAML files in the same namespace.
MainWindow.xaml
List.xaml
When I try to add List.xaml usercontrol to my mainwindow xaml (that is insert xaml from another file), it does not show up.
I insert usercontrol that exists in Lemosystem namespace and inside View folder.
xmlns:lemoview="clr-namespace:Lemosystem.View"
I add usercontrol to my MainWindow.xaml:
<lemoview:List/>
Nothing shows up. Here is my List XAML (code is the default):
<UserControl x:Class="Lemosystem.View.List"
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="300" d:DesignWidth="300">
<Grid>
<Label Content="What do you want to do today?" HorizontalAlignment="Left" Margin="10,96,-83,0" VerticalAlignment="Top" Height="44" Width="373" FontSize="24" FontWeight="Bold"/>
</Grid>
</UserControl>
I expect the label from my usercontrol to show up in MainWindow.xaml GUI, but it doesn't.
MainWindow.xaml
<Window x:Class="Lemosystem.View.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:lemocontroller="clr-namespace:Lemosystem.Controller"
xmlns:lemoview="clr-namespace:Lemosystem.View"
Title="{Binding Path=SystemName}" Height="603" Width="827"
ResizeMode="NoResize" WindowStartupLocation="Manual"
>
<Grid Name="Window" Margin="0,0,2,0">
<Grid.RowDefinitions>
<RowDefinition Height="0*"/>
<RowDefinition/>
</Grid.RowDefinitions>
...
<lemoview:List/>
...
</Grid>
</Window>
And how do I reference different elements inside my usercontrol (change their properties), when I want to change them in MainWindow.xaml and MainWindow.xaml.cs?
So, I created a project with :
List.Xaml
<UserControl x:Class="WpfApplication1.List"
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="300" d:DesignWidth="300">
<Grid>
<Label Content="{Binding TextToDisplay}"
HorizontalAlignment="Left"
Margin="10,96,-83,0"
VerticalAlignment="Top"
Height="44"
Width="373"
FontSize="24"
FontWeight="Bold" />
</Grid>
</UserControl>
ListViewModel.cs:
public class ListViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
private string textToDisplay;
public string TextToDisplay
{
get { return textToDisplay; }
set { textToDisplay = value; OnPropertyChanged("TextToDisplay"); }
}
public ListViewModel(string value)
{
TextToDisplay = value;
}
}
}
MainWindow.Xaml:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525"
xmlns:lemoview="clr-namespace:WpfApplication1">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<Button Content="Click Me" HorizontalAlignment="Center" Click="Button_OnClick"></Button>
<ListView Grid.Row="1" ItemsSource="{Binding MyList}"></ListView>
</Grid>
</Window>
MainWindow.xaml.cs:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = this;
MyList=new ObservableCollection<ListViewModel>();
}
private ObservableCollection<ListViewModel> myList;
public ObservableCollection<ListViewModel> MyList
{
get { return myList; }
set { myList = value; }
}
private void Button_OnClick(object sender, RoutedEventArgs e)
{
MyList.Add(new ListViewModel("MyValue"));
}
}
App.xaml:
<Application x:Class="WpfApplication1.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:wpfApplication1="clr-namespace:WpfApplication1"
StartupUri="MainWindow.xaml">
<Application.Resources>
<DataTemplate DataType="{x:Type wpfApplication1:ListViewModel}">
<wpfApplication1:List />
</DataTemplate>
</Application.Resources>
in App.xaml, I just defined the binding between List.xaml and ListViewModel.cs
the viewModel of MainWindow is itself.
after every Click on the button, a new ViewModel is created, added to the list with a defined value (you will need to modify this part, to set the value you want).
I hope it will help you ! it works for me.
How do you like to show something, if you put it il a row that has height ="0" ?
change it to :
<Window x:Class="Lemosystem.View.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:lemocontroller="clr-namespace:Lemosystem.Controller"
xmlns:lemoview="clr-namespace:Lemosystem.View"
Title="{Binding Path=SystemName}" Height="603" Width="827"
ResizeMode="NoResize" WindowStartupLocation="Manual"
>
<Grid Name="Window" Margin="0,0,2,0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<lemoview:List/>
</Grid>
I am using Caliburn Micro with WPF. I want to create an application with a menu on the left side, and a grid on the right side of the application. When clicking on a menu item, the grid on the right side, will change to another view. The another view will be in a separate file.
MainWindowView:
<UserControl x:Class="CMDemo.Views.MainWindowView"
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="300" d:DesignWidth="300">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="90*" />
<ColumnDefinition Width="210*" />
</Grid.ColumnDefinitions>
<StackPanel Name="LeftMenu">
<Button Name="ChangeDisplay" Content="Click Me"></Button>
<TextBlock x:Name="MyString"></TextBlock>
</StackPanel>
<Grid Grid.Column="1" x:Name="MainGridContent" />
</Grid>
MainWindowViewModel:
public class MainWindowViewModel : PropertyChangedBase
{
private UserControl mainGridContent;
private string myString;
public UserControl MainGridContent
{
get { return this.mainGridContent; }
set
{
this.mainGridContent = value;
NotifyOfPropertyChange(() => this.MainGridContent);
}
}
public string MyString
{
get { return this.myString; }
set
{
this.myString = value;
NotifyOfPropertyChange(() => this.MyString);
}
}
public void ChangeDisplay()
{
this.MainGridContent = new ChangeDisplayView();
this.MyString = "Testing....";
}
}
The changeDisplayViewModel:
public class changeDisplayViewModel: PropertyChangedBase
{
}
The changeDisplayView:
<UserControl x:Class="CMDemo.Views.changeDisplayView"
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="300" d:DesignWidth="300">
<Grid>
<TextBox content="Hello Caliburn Micro">
</Grid>
When I click the "Click Me" button the TextBlock "MyString" is updated and showing, but the usercontrol is not. What am I doing wrong?
Try changing MainGridContent to a changeDisplayViewModel rather than the view itself.