Can not bind View to ViewModel - wpf

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.

Related

Change List from MainWindow in WPF

I am trying to change a List that bind to DataGrid from MainWindow (The List is in another class).
How do i do it?
The List contains Tuple with 2 strings and i want to change just the second string when the user enters new values to a textBox in a dialog box (that he open after clicking on a button in the MainWindow.
(At the end i want the user to enter values in this dialog box and then show it in a list in another page (I mean another user control) so im open to hear also about different ways then this list of tuple bind to DataGrid).
How do i change this string from another page (I mean from the MainWindow)?
I tried to use MVVM the problem is that i dont find any connection between the mainWindow and the user control.
Name_List.xaml.cs:
namespace MyApp.Pages.SomeLists
{
public partial class Name_List: UserControl
{
private List<Tuple<string, string>> myNamesList = new List<Tuple<string, string>>();
public Name_List()
{
InitializeComponent();
myNamesList.Add(new Tuple<string, string>("First Name", your_name_bind));
myNamesList.Add(new Tuple<string, string>("Last Name", your_lastName_bind));
NamesGrid.ItemsSource = myNamesList;*/
}
}
}
Name_List.xaml:
<UserControl x:Class="MyApp.Pages.SomeLists.Name_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"
xmlns:local="clr-namespace:MyApp.Pages.SomeLists"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<DataGrid Name="NamesGrid" CanUserReorderColumns="True" CanUserResizeColumns="False" CanUserResizeRows="False" HorizontalAlignment="Left"
GridLinesVisibility="All">
</DataGrid>
</Grid>
</UserControl>
MainWindow.xaml:
<mui:ModernWindow x:Class="MyApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mui="http://firstfloorsoftware.com/ModernUI"
Title="App" IsTitleVisible="True"
Width="1200"
ContentSource="/Pages/Home.xaml">
<mui:ModernWindow.MenuLinkGroups>
<mui:LinkGroup DisplayName="Home page">
<mui:LinkGroup.Links>
<mui:Link DisplayName="home" Source="/Pages/Home.xaml" />
</mui:LinkGroup.Links>
</mui:LinkGroup>
<mui:LinkGroup DisplayName="Lists" >
<mui:LinkGroup.Links>
<mui:Link DisplayName="Open Lists" Source="/Pages/MainLists.xaml" />
</mui:LinkGroup.Links>
</mui:LinkGroup>
<mui:LinkGroup DisplayName="settings" GroupKey="settings">
<mui:LinkGroup.Links>
<mui:Link DisplayName="software" Source="/Pages/SettingsPage.xaml" />
</mui:LinkGroup.Links>
</mui:LinkGroup>
</mui:ModernWindow.MenuLinkGroups>
<mui:ModernWindow.TitleLinks>
<mui:Link x:Name="connect" DisplayName="connect"/>
<mui:Link DisplayName="settings" Source="/Pages/SettingsPage.xaml" />
<mui:Link DisplayName="help" Source="https://github.com" />
</mui:ModernWindow.TitleLinks>
</mui:ModernWindow>
MainWindow.xaml.cs
--There is a long code here... the relevant part is "connect_fun()" function that called after the user click on "OK" in the dialog that opened to him after he clicked on "connect" tab. the dialog contains 2 textBox.--
namespace MyApp
public partial class MainWindow : ModernWindow
{
private string name = "";
private string lastName = "";
//Here i create a Modern dialog in code.
.....
TextBox name_txt = new TextBox();
TextBox lastName_txt = new TextBox();
public MainWindow()
{
InitializeComponent();
}
private void connect_fun(object sender, RoutedEventArgs e)
{
name= name_txt.Text;
lastName = lastName_txt_txt.Text;
}
}
}
MainLists.xaml:
<UserControl x:Class=MyApp.Pages.MainLists"
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:mui="http://firstfloorsoftware.com/ModernUI"
xmlns:local="clr-namespace:MyApp.Pages"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Pages/Styles/BaseButtonStyle2.xaml"></ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="50"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0">
...
</Grid>
<Grid Style="{StaticResource ContentRoot}" Grid.Row="1">
<mui:ModernTab SelectedSource="/Pages/SomeLists/Name_List.xaml" Layout="Tab" >
<mui:ModernTab.Links>
<mui:Link DisplayName="Name List" Source="/Pages/SomeLists/Name_List.xaml"/>
<mui:Link DisplayName="Cars List" Source="/Pages/SomeLists/Cars_List.xaml"/>
</mui:ModernTab.Links>
</mui:ModernTab>
</Grid>
</Grid>
</UserControl>
I want to bind name and lastName to the dataGrid in Name_List.xaml (it means to your_name_bind and your_lastName_bind in myNamesList in my case).

Use base class control in Mainwindow XAML

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>

checking the checkbox on one page when click on button on another page WPF

I am in deep problem since 1 week. Actually, I have one button in MainWindow page say Button1 and one checkbox in Usercontrol page say CheckBox1. So the case is, when I click on Button1 then the CheckBox1 should show as Checked but nothing happening like this. I have Button1_Click method in MainWindow page where I invoked the CheckBox1.IsChecked = true by calling the instance of the UserControl class like
UserControl UC = new UserControl();
UC.CheckBox1.IsChecked =true;
I am posting a demo code for more clarification: This is the waay I want to do
My MainWindow.Xaml Page:
<Window x:Class="MyWpfApplicationDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MyWpfApplicationDemo"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Button x:Name="btnCheck" Width="110" Height="25" Margin="16,10,165,36" FontWeight="Medium" Click="btnCheck_Click" />
<local:MyUserControlDemo x:Name="MyUserControlDemo" Visibility="Visible" Margin="-54,-49,56,49" />
</Grid>
</Window>
My MainWindow.Xaml.cs page
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void btnCheck_Click(object sender, RoutedEventArgs e)
{
MyUserControlDemo us = new MyUserControlDemo();
us.chkCheckbox_CheckedChanged(null, null);
}
}
My UserControl.Xaml page
<UserControl x:Class="MyWpfApplicationDemo.MyUserControlDemo"
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>
<CheckBox x:Name="chkCheckbox" Margin="45,0,0,0" Grid.Column="2" Cursor="Hand" Width="100" Height="30" HorizontalAlignment="Center" VerticalAlignment="Center" Checked="chkCheckbox_CheckedChanged" />
</Grid>
</UserControl>
My UserControl.Xaml.cs Page
public partial class MyUserControlDemo : UserControl
{
static int count;
public MyUserControlDemo()
{
InitializeComponent();
}
public void chkCheckbox_CheckedChanged(object sender, RoutedEventArgs e)
{
chkCheckbox.IsChecked = true;
}
}
but after getting the true value the checkbox is not checked and I want to get this done as soon as possible because my project will be delivered after resolving this issue.
Please help me out.
Thanks in advance
If your checkbox and your usercontrol are in the same window just go to the parent of user control that is grid (probably), then go to the parent of grid that is MainWindow(probably) and set chkCheckbox.IsChecked = true;
example:
public void chkCheckbox_CheckedChanged(object sender, RoutedEventArgs e)
{
var grid = this.Parent as Grid;
if(grid != null)
{
var mainWindow = grid.Parent as MainWindow;
if(mainWindow != null)
{
mainWindow.chkCheckbox.IsChecked = true;
}
}
}
UPD:
<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"
x:Name="Main"
Title="MainWindow" Height="350" Width="525">
<Grid>
<local:UserControl1 Tag="{Binding ElementName=Main}"/>
<CheckBox Content="IsChecked?" x:Name="chkBox"/>
</Grid>
</Window>
private void Button_Click(object sender, RoutedEventArgs e)
{
var tag = Tag as MainWindow;
if (tag != null)
{
tag.chkBox.IsChecked = true;
}
}
UPD2:
You don't need to create Instance of UserControl in button click event, cuz you've already one in XAML, so you need to use it:
private void btnCheck_Click(object sender, RoutedEventArgs e)
{
MyUserControlDemo.chkCheckbox.IsChecked = true;
}
UPD3
Here's MainWindow XAML code:
<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"
x:Name="Main"
Title="MainWindow" >
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<local:UserControl1 Tag="{Binding ElementName=Main}"/>
<local:UserControl2 Grid.Column="1" Tag="{Binding ElementName=Main}" x:Name="Control2"/>
</Grid>
</Window>
UserControl1:
<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>
<Grid.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FFD3E424" Offset="0"/>
<GradientStop Color="#FF189724" Offset="1"/>
</LinearGradientBrush>
</Grid.Background>
<Button Width="200" Height="50" Content="CLICK ME" Click="Button_Click"/>
</Grid>
</UserControl>
using System.Windows;
using System.Windows.Controls;
namespace WpfApplication1
{
/// <summary>
/// Логика взаимодействия для UserControl1.xaml
/// </summary>
public partial class UserControl1 : UserControl
{
public UserControl1()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
var tag = Tag as MainWindow;
if (tag != null)
{
tag.Control2.checkBox.IsChecked = true;
}
}
}
}
UserControl2
<UserControl x:Class="WpfApplication1.UserControl2"
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>
<Grid.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FF000CFF" Offset="0"/>
<GradientStop Color="#FF03FF26" Offset="1"/>
</LinearGradientBrush>
</Grid.Background>
<CheckBox x:Name="checkBox" Content="CHECK ME" Foreground="White" FontSize="25" VerticalAlignment="Center" HorizontalAlignment="Center" VerticalContentAlignment="Center"/>
</Grid>
</UserControl>

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();
}
}
}

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>

Resources