Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
Sorry for the technically incorrect title, i am aware that partial view is more of an MVC term. However i unsure what the equivalent is in WPF.
I have a large form that the users need to complete. In order to assist them i wanted to split the view in two vertically and show helpful information in the right portion of the screen depending on what field they have selected on the left, or load quick select boxes in the right of the view which will then complete the items on the left.
I've been playing around for a few hours and have managed to split the view with a GridSplitter but from here i'm not sure where to go from here.
Could someone give me a few pointers on what to look at so I can progress. In the MVC world I would have had loaded it through Ajax and it would be done.
Update
This question got blocked, honestly im not entirely sure why. The question is valid and seems to be a logical comparison between the two frameworks. Im hoping that the ban is lifted as the answer was exactly what i was looking for and will definitely be helpful to others
Good question, and #Andy's comment points you in the correct direction. Here is how I would implement it:
View (MainView.xaml):
<Window x:Class="WpfApp4.MainView"
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:WpfApp4"
mc:Ignorable="d"
Title="MainView" Height="450" Width="800">
<Window.DataContext>
<local:MainViewVM />
</Window.DataContext>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<StackPanel Orientation="Vertical" VerticalAlignment="Center" HorizontalAlignment="Center">
<TextBlock Text="Box 1" />
<TextBox MinWidth="200" Name="TextBox1" GotFocus="TextBox1_GotFocus" />
<TextBlock Text="Box 2" />
<TextBox MinWidth="200" Name="TextBox2" GotFocus="TextBox2_GotFocus" />
</StackPanel>
<ContentControl Grid.Column="1" Content="{Binding SelectedUserControl}" />
</Grid>
</Window>
Code behind (MainView.xaml.cs):
using System.Windows;
namespace WpfApp4
{
/// <summary>
/// Interaction logic for MainView.xaml
/// </summary>
public partial class MainView : Window
{
public MainView()
{
InitializeComponent();
}
// I handle these in the code behind since this is pretty UI dependent.
private void TextBox1_GotFocus(object sender, RoutedEventArgs e)
{
((MainViewVM)DataContext).ChangeView(0);
}
private void TextBox2_GotFocus(object sender, RoutedEventArgs e)
{
((MainViewVM)DataContext).ChangeView(1);
}
}
}
ViewModel MainViewVM.cs:
using GalaSoft.MvvmLight;
using System.Collections.Generic;
using System.Windows.Controls;
namespace WpfApp4
{
public class MainViewVM : ObservableObject
{
private UserControl _SelectedUserControl;
public UserControl SelectedUserControl
{
get => _SelectedUserControl;
set => Set(ref _SelectedUserControl, value);
}
public List<UserControl> ViewOptions { get; set; }
public MainViewVM()
{
ViewOptions = new List<UserControl>()
{
new Box1View(),
new Box2View()
};
ChangeView();
}
public void ChangeView(int index = 0)
{
if (index < ViewOptions.Count && index >= 0)
{
SelectedUserControl = ViewOptions[index];
}
}
}
}
Then my 2 UserControls...
Box1View.xaml
<UserControl x:Class="WpfApp4.Box1View"
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:WpfApp4"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid Background="Yellow">
<TextBlock Text="Box 1" />
</Grid>
</UserControl>
Box2View.xaml
<UserControl x:Class="WpfApp4.Box2View"
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:WpfApp4"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid Background="Pink">
<TextBlock Text="Box 2" />
</Grid>
</UserControl>
Here are what the two views look like:
Related
Learning WPF Core 3.1 WPF MVVM pattern, using Visual Studio 2019 4.8.04084.
I have a MainWindow with the following (boilerplate excluded)
<Window>
<Grid
Width="1024"
Height="768"
Margin="0,0,0,0">
<Grid.RowDefinitions>
<RowDefinition Height="100" />
</Grid.RowDefinitions>
<usercontrols:CustomerMaintenanceControl
x:Name="CustomerMaintenance"
Grid.Row="0"
Height="109"
VerticalAlignment="Top" />
</Grid>
</Window>
The CustomerMaintenanceControl user control looks like this:
<UserControl
x:Class="Redacted.UserControls.CustomerMaintenanceControl"
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:usercontrols="clr-namespace:Redacted.UserControls"
xmlns:vm="clr-namespace:Redacted.ViewModels"
d:DesignHeight="450"
d:DesignWidth="800"
Loaded="UserControl_Loaded"
mc:Ignorable="d">
<UserControl.Resources>
<vm:CustomerMaintenanceViewModel x:Key="viewModel" />
</UserControl.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<usercontrols:CustomerMaintenanceGridControl
x:Name="gridControl"
Grid.Row="0"
Height="200"
DataContext="{StaticResource viewModel}" />
<usercontrols:CustomerMaintenanceDetailControl
x:Name="detailControl"
Grid.Row="1"
Width="800"
Height="200"
HorizontalAlignment="Left"
VerticalAlignment="Center"
DataContext="{StaticResource viewModel}" />
</Grid>
</UserControl>
Here's the CustomerMaintenanceDetailControl, where the issue is:
<UserControl
x:Class="Redacted.UserControls.CustomerMaintenanceDetailControl"
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:local="clr-namespace:Redacted"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
d:DesignHeight="450"
d:DesignWidth="800"
mc:Ignorable="d">
<Grid Margin="0,0,0,325">
<Grid.RowDefinitions>
<RowDefinition />
</Grid.RowDefinitions>
<TabControl
x:Name="tabControl"
Grid.Row="0"
Margin="0,0,0,0">
<TabItem>
<TabItem.Header>
<StackPanel Orientation="Horizontal">
<TextBlock>General</TextBlock>
</StackPanel>
</TabItem.Header>
<StackPanel>
<TextBox
x:Name="companynmTextbox"
Width="322"
Margin="0,32,228,0"
HorizontalAlignment="Left"
IsReadOnly="True"
Text="{Binding Path=Entity.Companynm}" />
</StackPanel>
</TabItem>
</TabControl>
</Grid>
</UserControl>
So the CustomerMaintenanceControl has two user controls in it, a CustomerMaintenanceGridControl that has a DataGrid and then a CustomerMaintenanceDetailControl which has a tab control and a bound TextBox. The grid is pulling data in fine, so the model and data layer are working. However the 'companyNmTextBox' control on CustomerMaintenanceGridControl is displaying nothing.
There are no binding errors in VS. In addition, when I run the application and open the Live Visual Tree, I can open the properties for 'companyNmTextBox' and under Inherited\DataContext I have my 'Customers' ObservableCollection there and populated, and my 'Entity' property on the model populated with the data for the first Customer. Yet nothing showing onscreen.
Since people are voting to close because of 'debugging details' (?) - the debugging details are in the last paragraph - there are no binding or errors in Visual Studio, and everything appears bound OK in the Live Visual Tree/ The 'desired behaviour' is that the textbox displays the value of the thing that it is bound to. If there are further debugging steps I could investigate I'd be delighted to hear them.
Your Entity has to implement INotifyPropertyChanged interface
public class Entity : INotifyPropertyChanged
{
private string companynm;
public string Companynm
{
get
{
return companynm;
}
set
{
this.companynm = value;
NotifyPropertyChanged();
}
}
...
private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
Also TextBox companynmTextbox has the property IsReadOnly set to true, so in that case I would modify the binding.
Text="{Binding Path=Entity.Companynm, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
It was a typo to the call to RaisePropertyChanged() in the ViewModel the CustomerMaintenanceDetailControl is using.
I had:
private Customer _entity = new Customer();
public Customer Entity
{
get { return _entity; }
set
{
_entity = value;
RaisePropertyChanged("Customer"); // <- problem here
}
}
I should have had:
private Customer _entity = new Customer();
public Customer Entity
{
get { return _entity; }
set
{
_entity = value;
RaisePropertyChanged("Entity"); // <- doh
}
}
I wan to create a base class which consits properties of both User contorl and window and that baseclass control used in my Mainwindow.xaml.
Below code i am using but getting following error "Partial declarations of 'MainWindow' must not specify different base classes"
Usercontrol1.xaml
<UserControl x:Class="WpfApplication1.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:WpfApplication1"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<TextBox x:Name="textBox" HorizontalAlignment="Left" Height="23" Margin="80,46,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120"/>
<Button x:Name="button" Content="Button" HorizontalAlignment="Left" Margin="80,82,0,0" VerticalAlignment="Top" Width="75" Click="button_Click"/>
</Grid>
</UserControl>
UserControl1.xaml.cs
namespace WpfApplication1
{
public class baseclass : UserControl
{
public Button textBox { get; set; }
public baseclass()
{
}
private void button_Click(object sender, RoutedEventArgs e)
{
if (!string.IsNullOrEmpty(textBox.ToString()))
{
}
}
}
public partial class UserControl1
{
public UserControl1()
{
InitializeComponent();
}
}
}
Now Problem is that how can i use usecontrol in my Main window.code for main window below
Mainwindow.xaml.cs
namespace WpfApplication1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
}
}
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"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApplication1"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
</Grid>
</Window>
I'm not sure if I'm missing something obvious or others have missed something obvious! I can add baseclass to MainWindow just fine with:
<Window x:Class="WpfApp2.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:WpfApp2"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<local:baseclass />
</Window>
The key thing is local: xmlns namespace that's defined as xmlns:local="clr-namespace:WpfApp2"
If you're not merely cargo culting the code, you can see how the above will work for you.
Now the real answer for the question you didn't ask: you're doing this wrong! The textbox in baseclass will never work because you haven't initialised it as a UserControl (there's more to this than just inheriting from UserControl) Learn MvvM and stop relying on code behind. Your life will get much easier.
i want to use base user control in main window this is what i ma trying to do
You can't. A top-level window class cannot inherit from System.Windows.Controls.UserControl. It must inherit from a System.Windows.Window. So it is not possible to define a common base class for both user controls and windows in WPF.
You can change the base class of UserControl1 though but you must specify the same base class in both the XAML markup and the code-behind file:
UserControl1.xaml.cs:
public partial class UserControl1 : baseclass
{
public UserControl1()
{
InitializeComponent();
}
}
UserControl1.xaml:
<local:baseclass x:Class="WpfApplication1.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:WpfApplication1"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<TextBox x:Name="textBox" HorizontalAlignment="Left" Height="23" Margin="80,46,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120"/>
<Button x:Name="button" Content="Button" HorizontalAlignment="Left" Margin="80,82,0,0" VerticalAlignment="Top" Width="75" Click="button_Click"/>
</Grid>
</local:baseclass>
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I have 2 xaml window and i want to store data between windows.How can i do?
Refer the below code sample for passing using constructor.
<Window x:Class="DelegateComd_Learning.Login"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Login" Height="300" Width="300">
<Grid>
<StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Username"/>
<TextBox x:Name="txtUsername" Width="100"/>
</StackPanel>
<Button Content="Login" Click="Button_Click"/>
</StackPanel>
</Grid>
public partial class Login : Window
{
public Login()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Window1 win = new Window1(txtUsername.Text);
win.Show();
}
}
<Window x:Class="DelegateComd_Learning.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Grid>
<TextBlock x:Name="txtDisplayUsername"/>
</Grid>
public partial class Window1 : Window
{
public Window1(string username)
{
InitializeComponent();
txtDisplayUsername.Text = username;
}
}
I'm new in WPF and I'm creating a control. This control contains a DataGrid and some other WPF controls.
I created my Control as below:
<UserControl x:Class="MyControls.MyControl"
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="329" d:DesignWidth="535" >
<Grid>
<DataGrid Margin="6,25,6,35" Name="dataGrid" SelectionUnit="CellOrRowHeader" x:FieldModifier="public" HeadersVisibility="All"/>
<OtherControl HorizontalAlignment="Left" x:Name="otherControl" Height="34" VerticalAlignment="Bottom" Width="523" x:FieldModifier="private"/>
<Label Content="caption" Height="24" HorizontalAlignment="Left" Name="captionLabel" VerticalAlignment="Top" Foreground="#FF2626D1" x:FieldModifier="private"/>
</Grid>
</UserControl>
So, everything goes well so far, then I create a container UserControl which has in it my control created previously:
<UserControl x:Class="MyContainers.MyContainer"
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" xmlns:my="clr-namespace:MyControls">
<Grid>
<my:MyControl>
</my:MyControl>
</Grid>
What I can not do is the following:
<my:MyControl>
<my:MyControl.dataGrid>
</my:MyControl.dataGrid>
</my:MyControl>
I previously set the datagrid's property of FieldModifier as public in order to get access to it in another xaml, but it raises an error from visual studio.
I need to "expose" my dataGrid in order to be able to add columns and their styles.
I would like to be able to do something like this:
<my:MyControl.dataGrid.Columns >
<DataGridTextColumn />
<DataGridTextColumn />
...
<DataGridTextColumn />
</my:MyControl.dataGrid.Columns>
So, is not enough to set the datagrid's property of FieldModifier as public?
Do I need to do something else? How can I achieve this? Is this even possible?
I hope someone can help me. Thank you in advance.
You cannot access the child DataGrid as MyControl.dataGrid -- MyControl has no property named "dataGrid".
You might try adding a dependency property of type ObservableCollection<DataGridColumn> to MyControl, and modify the dataGrid columns whenever that collection changes.
EDIT:
Whipped together a quick example for you:
UserControl code:
public partial class UserControl1 : UserControl
{
public static readonly DependencyProperty ColumnsProperty = DependencyProperty.Register("Columns", typeof(ObservableCollection<DataGridColumn>), typeof(UserControl1));
public ObservableCollection<DataGridColumn> Columns
{
get { return (ObservableCollection<DataGridColumn>)GetValue(ColumnsProperty); }
set { SetValue(ColumnsProperty, value); }
}
public UserControl1()
{
Columns = new ObservableCollection<DataGridColumn>();
Columns.CollectionChanged += (s, a) =>
{
dataGrid.Columns.Clear();
foreach (var column in this.Columns)
dataGrid.Columns.Add(column);
};
InitializeComponent();
}
}
UserControl xaml:
<UserControl x:Class="WpfApplication1.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">
<Grid>
<DataGrid x:Name="dataGrid" AutoGenerateColumns="False"/>
</Grid>
so you can use it like:
<Grid>
<l:UserControl1>
<l:UserControl1.Columns>
<DataGridTextColumn Header="Col1"/>
<DataGridTextColumn Header="Col2"/>
</l:UserControl1.Columns>
</l:UserControl1>
</Grid>
Please excuse this novice question, but I'm ramping up on Silverlight and MVVM Light. I created a view called MyView.xaml and a corresponding MyViewModel.cs.
MyView.xaml
<navigation:Page x:Class="Dashboard.Views.MyView"
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:Dashboard.ViewModels"
xmlns:controls="clr-namespace:Dashboard.Controls"
mc:Ignorable="d"
xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
d:DesignWidth="640" d:DesignHeight="480"
Title="MyView Page" xmlns:toolkit="http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit">
<navigation:Page.Resources>
<vm:MyViewModel x:Key="MyViewModel" />
</navigation:Page.Resources>
<navigation:Page.DataContext>
<Binding Source="{StaticResource MyViewModel}"/>
</navigation:Page.DataContext>
<Grid x:Name="LayoutRoot">
<StackPanel Orientation="Vertical" Style="{StaticResource LoginControlsStackPanelStyle}" HorizontalAlignment="Center" VerticalAlignment="Center">
<toolkit:DataForm Name="dataForm1" CurrentItem="{Binding}"/>
</StackPanel>
</Grid>
MyViewModel.cs
namespace Dashboard.ViewModels
{
public class MyViewModel : ViewModelBase
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
}
When I run the project, my form renders the IsInDesignMode property. I obviously do not want this. How can I prevent the base class property from rendering in the dataform?
Thanks.
Andrew
If you only want to prevent one filed from showing up, you can subscribe to the AutoGeneratingField event and set the Cancel flag on the events args to true. If you want to implement your own layout, you can set the AutoGeneratingFields flag to false and provide your own templates.