Use base class control in Mainwindow XAML - wpf

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>

Related

WPF Radio Buttons

I am creating Radio button on Visual Studio and I am having a trouble with Binding
This is my button:
<RadioButton VericalAlignment="Center" GroupName="group1" Content="name"></RadioButton>
I want that if the button was selected then the value of {"someString " + Content Value} will be bind
to SomeClass.variable
is something like this possible?
Thank you!
Something like this should work:
XAML:
<Window x:Class="StackOverflowRadioButton.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:StackOverflowRadioButton"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid Margin="81,36,-81,-36">
<RadioButton Content="RadioButton" HorizontalAlignment="Left" Margin="111,135,0,0" VerticalAlignment="Top"
Name="myRadioButton" Checked="myRadioButton_Checked"/>
</Grid>
CS file:
using System.Windows;
namespace StackOverflowRadioButton
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public string someVariable;
public MainWindow()
{
InitializeComponent();
}
private void myRadioButton_Checked(object sender, RoutedEventArgs e)
{
someVariable = "someString " + myRadioButton.IsChecked;
}
}
}

bind the text box of user control through mainwindow text

I am working on WPF project. I have created a user control name as "CanLogPaneView". this user control contains a Text box called "txt_CanLog".
I have bind this Text box as mentioned below:
<UserControl x:Class="CANCONTROL.CanLogPaneView"
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:CANCONTROL"
xmlns:ViewModels="clr-namespace:CANCONTROL.ViewModels;assembly=CANCONTROL.ViewModels"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<UserControl.Resources>
<DataTemplate x:Key="MainWindowViewModel" DataType="{x:Type ViewModels:MainWindowViewModel}">
</DataTemplate>
</UserControl.Resources>
<DockPanel>
**<TextBox x:Name="txt_CanLog" Text="{Binding Text, Source={StaticResource MainWindowViewModel}}" >**
</TextBox>
</DockPanel>
</UserControl>
So I have bind the text box with mainwindow property Text. My main window have a view model. there I defined the property Text as mentioned below:
public string text = string.Empty;
public string Text
{
get
{
return text;
}
set
{
text = text + value;
}
}
in Main window code: MainWindow.xaml.cs I am adding text like
this.ViewModel.Text = "\n\nAPPLICATION CONFIGURATION\r\n";
What I want is through mainwindow.xaml.cs code I want to print some data in CanLogPaneView.xaml's textBox
Your MainWindowViewModel should be binded to your Usercontrol's DataContext instead.
Also, implement INotifyPropertyChanged in your MainWindowViewModel and RaisePropertyChange at your "Text" setter
Something like the following
<Window x:Class="WpfTestProj.MainWindow"
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"
xmlns:local="clr-namespace:WpfTestProj"
Title="MainWindow" Height="350" Width="525"
d:DataContext="{d:DesignInstance Type=local:MainViewModel, IsDesignTimeCreatable=False}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
</Grid.RowDefinitions>
<TextBox Text="{Binding Text}" />
</Grid>
public class MainViewModel : ViewModelBase
{
private string _text;
public string Text
{
get { return _text; }
set
{
_text = value;
OnPropertyChanged();
}
}
}

Navigating to wpf page based on timer

I'm trying to navigate to a different page from my MainWindow in a WPF application. The MainWindow just has some welcome text and I want it to move to another page after 4 seconds. The timer is working just fine but I am getting an error that says,
"Error 1 'UbiTutorial.MainWindow' does not contain a definition for 'Frame' and no extension method 'Frame' accepting a first argument of type 'UbiTutorial.MainWindow' could be found (are you missing a using directive or an assembly reference?) c:\users\thomas\documents\visual studio 2012\Projects\UbiTutorial\UbiTutorial\MainWindow.xaml.cs 54 22 UbiTutorial"
in my method
if (introTime > 4)
{
this.Frame.Navigate(typeof(Touch));
}
Visual Studio is complaining about the Frame part of it.
Frame is a Control Type not a Control Instance, without seeing your Xaml I have no idea of what the name of the Frame that you added is, it probably defaulted to frame1 that is what you will need to use to access the Navigate Method. Hopefully this will give you an idea.
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">
<Grid>
<Frame Height="100" HorizontalAlignment="Left" Margin="10,10,0,0" Name="frame1" VerticalAlignment="Top" Width="200" />
</Grid>
</Window>
MainWindow.xaml.cs
using System.Windows.Threading;
namespace WpfApplication1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
DispatcherTimer introTime = new DispatcherTimer();
public MainWindow()
{
InitializeComponent();
introTime.Interval = TimeSpan.FromSeconds(4);
introTime.Tick += new EventHandler(introTime_Tick);
introTime.Start();
}
void introTime_Tick(object sender, EventArgs e)
{
//this.frame1.Navigate(new Uri(#"http://www.google.com"));
this.frame1.Navigate(new UserControl1());
}
}
}
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"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300" Background="Red" >
<Grid>
</Grid>
</UserControl>

How to Expose a Control in XAML

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>

Can not bind View to ViewModel

I'm trying to do a simplest thing: bind a View to ViewModel, but for some reason it doesn't work.
I've got MainWindow:
<Window x:Class="ImagesToAmazon.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:v="clr-namespace:ImagesToAmazon.View"
xmlns:vm="clr-namespace:ImagesToAmazon.ViewModel" >
<Window.Resources>
<DataTemplate DataType="{x:Type vm:MainViewModel}">
<v:MainControl />
</DataTemplate>
</Window.Resources>
<Grid>
</Grid>
MainViewModel:
namespace ImagesToAmazon.ViewModel{
public class MainViewModel {
}}
MainControl:
<UserControl x:Class="ImagesToAmazon.View.MainControl"
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">
<StackPanel>
<Button Content="Button" Height="23" Name="button1" Width="75" />
</StackPanel>
Also, I override App.OnStartup to set MainWindow context:
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
var window = new MainWindow();
var viewModel = new ViewModel.MainViewModel();
window.DataContext = viewModel;
window.Show();
}
}
All compiles, but I don't see my button from MainControl.
Any clues?
In the main window, replace the Grid with
<ContentControl Content="{Binding }" />
This will attempt to use the current DataContext as the content of the control, and it will use the DataTemplate u defined earlier.

Resources