How can we set source of data binding to this in xaml? - c#

How can I write this expression in xaml?
Binding binding = new Binding("Logo");
binding.Source = this;
binding.Converter = new ToImageConverter();
imgLogo.SetBinding(Image.SourceProperty, binding);
Please note that I don't want to set DataContext = this in xaml.cs. I want to set the Source to be this.
Thanks in advance :)
Edit:
This is my simple usercontrol:
<UserControl x:Class="SilverlightApplication4.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"
d:DesignHeight="300" d:DesignWidth="400">
<Grid x:Name="LayoutRoot" Background="White">
<TextBlock Text="{Binding Tooltip, RelativeSource={RelativeSource Self}}"/>
</Grid>
</UserControl>
This is my cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
namespace SilverlightApplication4
{
public partial class MainPage : UserControl
{
public static readonly DependencyProperty ToolTipProperty
= DependencyProperty.Register("ToolTip", typeof(string), typeof(MainPage),
new PropertyMetadata(string.Empty));
public string Tooltip
{
get { return GetValue(ToolTipProperty) as string; }
set { SetValue(ToolTipProperty, value); }
}
public MainPage()
{
InitializeComponent();
this.Loaded += new RoutedEventHandler(MainPage_Loaded);
}
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
Tooltip = "Test tooltip.";
}
}
}
The binding doesn't work.

Try using "{Binding Logo, RelativeSource={RelativeSource Self}}" (converter omitted for clarity).
edit:
Based on your updated code, you want:
<UserControl x:Class="SilverlightApplication4.MainPage"
x:Name=MyUserControl
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"
d:DesignHeight="300" d:DesignWidth="400">
<Grid x:Name="LayoutRoot" Background="White">
<TextBlock Text="{Binding Tooltip, ElementName=MyUserControl}"/>
</Grid>
</UserControl>

You should do this in the XAML:
<TextBlock Id="TextBlock1" Text="{Binding Tooltip}"/>
and in your code (Constructor / UserControl_Loaded) you should do:
TextBlock1.DataContext = this;
Also you might need to Implement INotifyPropertyChanged
and Raise OnPropertyChanged Event in the Property's Set
Why don't you want to do it in code?

Related

How to instantiate UserControl and add Items to its Container in XAML

I have the following UserControl:
<UserControl x:Class="UserControlTest.UserControl"
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 x:Name="MainPanel" Background="White">
<TextBlock Text="BasePanel"/>
</StackPanel>
And my MainWindwo.XAML:
<Window x:Class="UserControlTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:UC="clr-namespace:UserControlTest"
Title="MainWindow" Height="350" Width="525">
<DockPanel Name="dpMain">
<UC:Control x:Name="ucBaseControl" />
</DockPanel>
In the code-behind MainWindow.xaml.cs:
namespace UserControlTest
{
/// <summary>
/// Interaktionslogik für MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
TextBox tbWorld = new TextBox();
tbWorld.Text = "Hello World";
ucBaseControl.MainPanel.Children.Add(tbWorld);
}
}
}
Is there a way to achieve this in XAML to avoid code-behind?
Thank you very much in advance!
You could try to do something like:
XAML:
<UserControl x:Class="WpfApplication1.BaseControl"
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 x:Name="root">
<TextBlock>I'm from base</TextBlock>
<StackPanel x:Name="newPanel">
</StackPanel>
</StackPanel>
</UserControl>
Code behind:
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Markup;
namespace WpfApplication1
{
[ContentProperty("NewControls")]
public partial class BaseControl : UserControl
{
public UIElementCollection NewControls
{
get { return (UIElementCollection)GetValue(NewControlsProperty); }
set { SetValue(NewControlsProperty, value); }
}
public static readonly DependencyProperty NewControlsProperty = DependencyProperty.Register("NewControls", typeof(UIElementCollection), typeof(BaseControl));
public BaseControl()
{
InitializeComponent();
this.NewControls = new UIElementCollection(this, this);
this.Loaded += BaseControl_Loaded;
}
void BaseControl_Loaded(object sender, RoutedEventArgs e)
{
foreach (UIElement element in NewControls.Cast<UIElement>().ToList())
{
NewControls.Remove(element);
this.newPanel.Children.Add(element);
}
}
}
}
And in the other control or window:
xmlns:local="clr-namespace:WpfApplication1"
...
<local:BaseControl>
<TextBlock>I'm from new</TextBlock>
</local:BaseControl>
Not sure it perfectly fits your needs but may serve as a good base.
Here my solution.
My UserControl:
<UserControl x:Class="ucFancyMenu" x:Name="MySelf"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid>
<Label Height="30" VerticalAlignment="Top" Background="#F0F">So Fancy</Label>
<ItemsControl Margin="0 30 0 0" ItemsSource="{Binding ElementName=MySelf, Path=Items}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</Grid>
</UserControl>
The UserControl Class:
<Markup.ContentProperty("Items")> _
Public Class ucFancyMenu
Public Property Items As New List(Of UIElement)
End Class
How to use it in other Xamls:
<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid>
<local:ucFancyMenu>
<Button>FancyBtn 1</Button>
<Button>FancyBtn 2</Button>
<Button>FancyBtn 3</Button>
<Button>FancyBtn 4</Button>
<Button>FancyBtn 5</Button>
<Button>FancyBtn 6</Button>
<Button>FancyBtn 7</Button>
</local:ucFancyMenu>
</Grid>
</Window>

Get value of a string Variable from MainPage.xaml.cs file to MainPage.xaml file in Windows Phone

I have created a project in which the MainPage.xaml.cs is like the following:
using System;
using System.Collections.Generic;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
namespace DemoApp
{
public partial class MainPage : PhoneApplicationPage
{
public string ImagePath = "/Images/Flower.png";
public StartPage()
{
InitializeComponent();
}
}
}
And I have created the MainPage.xaml like the following:
<phone:PhoneApplicationPage
x:Class="DemoApp.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
mc:Ignorable="d"
shell:SystemTray.IsVisible="True">
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<Image x:Name="ImageShow" Source=""/>
</Grid>
</phone:PhoneApplicationPage>
Now my question is, is there any way to get the value of the ImagePath (string) to the Image called ImageShow as Source? Is there any way to do it from MainPage.xaml and using DataBinding in this case without creating any new class?
You need to convert ImagePath into property as you are cannot bind to fields
public partial class MainPage : PhoneApplicationPage
{
public string ImagePath { get; set; }
public MainPage()
{
ImagePath = "/Images/Flower.png";
InitializeComponent();
}
}
give page some name and bind Image.Source to ImagePath property
<phone:PhoneApplicationPage ... x:Name="myPage">
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<Image x:Name="ImageShow" Source="{Binding ElementName=myPage, Path=ImagePath}"/>
</Grid>
</phone:PhoneApplicationPage>
Use DataContext in your codeBehind
public string ImagePath = "/Images/Flower.png";
public StartPage()
{
InitializeComponent();
this.DataContext=this;
}
Then you use in your .xaml you binding
<Image x:Name="ImageShow" Source="{Binding ImagePath}"/>
You should create DependencyProperty
public string ImagePath
{
get { return (string) GetValue(ImagePathProperty); }
set { SetValue(ImagePathProperty, value); }
}
public static readonly DependencyProperty ImagePathProperty =
DependencyProperty.Register("ImagePath", typeof(string), typeof(MainPage), new PropertyMetadata(""));
This will create property available for binding, after this You can bind to it in Image:
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<Image x:Name="ImageShow" Source="{Binding Path=ImagePath, RelativeSource={RelativeSource AncestorType=PhoneApplicationPage}}"/>
</Grid>
Add your variable as a resource from codebehind:
myWindow.Resources.Add("ImagePath", "/Images/Flower.png");
myWindow.DataContext = ImagePath;
Access in XAML:
<Image x:Name="ImageShow" Source={Binding Path=ImagePath}"/>

WPF Window does not load UserControl

I guess I've got a pretty simple problem. I'm tying show a usercontrol via contentcontrol.
What a did is to create this usercontrol...
<UserControl x:Class="Exxeta.ModeldrivenCostEstimation.WPF.UserControlModelAnalysis"
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="350" d:DesignWidth="525">
<Grid Margin="0,0,0,0">
<Grid Background="#FFE5E5E5" HorizontalAlignment="Right" Width="489" Margin="0,93,11,0" Height="164" VerticalAlignment="Top" >
<DataGrid x:Name="DataGrid" HorizontalAlignment="Left" VerticalAlignment="Top"
Width="489" AutoGenerateColumns="False" ItemsSource="{Binding ViewModelModelAnalysis.GridObjects}" CanUserResizeRows="False" CanUserResizeColumns="False">
</DataGrid>
</Grid>
</Grid>
and declared the contentControl on my mainwindow
<Window x:Class="WPF.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Test" Height="350" Width="525" ResizeMode="NoResize" Background="#FFE5E5E5">
<ContentControl Name="Content" Width="Auto" Opacity="1" Background="Transparent" ></ContentControl>
</Window>
.. And as I read I create the windows like this.
public MainWindow(***)
{
InitializeComponent();
model = new BasicViewModel();
UserControl c1 = new UserControlModelAnalysis();
this.Content = c1;
this.DataContext = model;
}
But the content is not shown by the window. Did I missed something there ?
Hope you can help me out of this little issue.
Thanks for your help
Iki
Edit: Whats happening is that the MainWindow.Content PUBLIC field is hiding the base classes Content property. You are setting the content field to your UserControl which is also a ContentControl hence no type cast error. Because The MainWindow.Content field is not a dependency property the UI is never updated and your content is not shown.
Answer: Rename your ContentControl and set the content property on the control.
This works.
Xaml
<Window x:Class="Example_Project.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>
<ContentControl x:Name="currentContent"/>
</Grid>
</Window>
Code Behind
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
currentContent.Content = new Content1();
}
}
You should not initiate this from code behind although you can. Below is how you can use your control. The 'xmlns:local' definition add the local assembly and gives you access to the control.
<Window x:Class="WpfApplication3.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication3"
Title="MainWindow" Height="350" Width="525">
<Grid>
<local:UserControl1></local:UserControl1>
</Grid>
</Window>
...
<UserControl x:Class="WpfApplication3.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">
<Grid>
<TextBlock>Test</TextBlock>
</Grid>
</UserControl>
This could be achieved from code behind like below. You could have your usercontrols in there like I add the buttons to the content.
<Window x:Class="WpfApplication4.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>
<ContentControl x:Name="Content"></ContentControl>
</Grid>
</Window>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WpfApplication4
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Loaded += MainWindow_Loaded;
}
private Button m_Button1;
private Button m_Button2;
void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
Loaded -= MainWindow_Loaded;
m_Button1 = new Button { Content = "Button1" };
m_Button2 = new Button { Content = "Button2" };
m_Button1.Click += button1_Click;
m_Button2.Click += m_Button2_Click;
Content.Content = m_Button1;
}
void m_Button2_Click(object sender, RoutedEventArgs e)
{
Content.Content = m_Button1;
}
void button1_Click(object sender, RoutedEventArgs e)
{
Content.Content = m_Button2;
}
}
}
Thanks all of you for your respones. Its running now. What I basicly did is to drag and drop one of my UserControles onto the Window and load the next one like
this.currentContent.Content = new Content1().. like I already did..and it works. I guess that what kicks said explained my problem right :-)
Thanks
I found that the Loaded event was not raised when I tried to show it in the constructor. This is not a good idea.
public partial class MyDockpaneView : UserControl
{
public MyDockpaneView ()
{
InitializeComponent();
Loaded += MyDockpaneView _Loaded;
MyDockpaneViewModel.Show();
}
MyDockpaneView _Loaded() is not called unless comment out MyDockpaneView.Show();

assign itemsSource of DataGrid inside usercontrol in wpf

I am quite new to wpf so maybe I am missing something obvious here. I have found a similar question in stackoverflow and tried the solution (which is implemented in the code given below) but was not able to get it work. The link is here. Let me explain the problem. I am working with framework 2010.
I have a usercontrol which contains 1 datagrid and 3 buttons. The xaml of the same is as below.
<UserControl x:Class="RadarControls.RadarDataGrid"
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:diagnostics="clr-namespace:System.Diagnostics;assembly=WindowsBase"
xmlns:local="clr-namespace:RadarControls"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="25" />
</Grid.RowDefinitions>
<DataGrid Name="myGrid" Grid.ColumnSpan="3" ItemsSource="{Binding}" AutoGenerateColumns="True"></DataGrid>
<Button Content="Add" Grid.Row="1" Height="23" Margin="0,2,2,0" HorizontalAlignment="Left" Name="btnAdd" Width="100" />
<Button Content="Delete" Grid.Column="1" Grid.Row="1" Margin="0,2,2,0" Height="23" HorizontalAlignment="Left" Name="btnDelete" Width="100" />
<Button Content="Save" Grid.Column="2" Grid.Row="1" Height="23" Margin="0,2,0,0" HorizontalAlignment="Left" Name="btnSave" Width="100" />
</Grid>
</UserControl>
The xaml of my window where i am using this usercontrol is as below
<Window x:Class="RadarStudio.Users"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ctrls="clr-namespace:RadarControls;assembly=RadarControls"
xmlns:vm='clr-namespace:RadarViewModel.Users;assembly=RadarViewModel'
Title="Users" Height="300" Width="300">
<Grid >
<ctrls:RadarDataGrid Name="grid1" DataContext="{Binding str}"></ctrls:RadarDataGrid>
</Grid>
My window code behind is as follows
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Collections.ObjectModel;
namespace RadarStudio
{
/// <summary>
/// Interaction logic for Users.xaml
/// </summary>
public partial class Users : Window
{
public Users()
{
InitializeComponent();
//this.DataContext = this;
str.Add("dhaval");
str.Add("ravinder");
}
public ObservableCollection<string> str = new ObservableCollection<string>();
}
}
I tried so many things but I am not able to get the strings on my grid.
Please help!
Thanks in advance!
Regards,
Samar
You can only bind to public properties! Make str as property.
From MSDN: The properties you use as binding source properties for a binding must be public properties of your class. Explicitly defined interface properties cannot be accessed for binding purposes, nor can protected, private, internal, or virtual properties that have no base implementation.
You cannot bind to public fields.
As Zabavsky mentioned, WPF binding works with properties of an object, but not fields.
Try changing str to property:
public partial class Users : Window
{
public Users()
{
InitializeComponent();
this.DataContext = this;
str = = new ObservableCollection<string>();
str.Add("dhaval");
str.Add("ravinder");
}
public ObservableCollection<string> str { get; set; }
}
Try this.....
I just checked for your sample data it worked fine i don't test further.
Check thoroughly....
I Just Modified Your Code, and Posted below.
<UserControl x:Class="RadarControls.RadarDataGrid"
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:diagnostics="clr-namespace:System.Diagnostics;assembly=WindowsBase"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300" >
<!--xmlns:local="clr-namespace:RadarControls"-->
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="25" />
</Grid.RowDefinitions>
<DataGrid Name="myGrid" Grid.ColumnSpan="3" AutoGenerateColumns="True"></DataGrid> //Data Grid Is Modified
<Button Content="Add" Grid.Row="1" Height="23" Margin="0,2,2,0" HorizontalAlignment="Left" Name="btnAdd" Width="100" />
<Button Content="Delete" Grid.Column="1" Grid.Row="1" Margin="0,2,2,0" Height="23" HorizontalAlignment="Left" Name="btnDelete" Width="100" />
<Button Content="Save" Grid.Column="2" Grid.Row="1" Height="23" Margin="0,2,0,0" HorizontalAlignment="Left" Name="btnSave" Width="100" />
</Grid>
</UserControl>
The xaml of my window where you are supposed to use this usercontrol
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace RadarControls
{
/// <summary>
/// Interaction logic for RadarDataGrid.xaml
/// </summary>
public partial class RadarDataGrid : UserControl
{
public RadarDataGrid()
{
InitializeComponent();
}
public DataGrid RadarGrid//New Public Class is added
{
get { return myGrid; }
}
}
}
The xaml of window where you are supposed to use this usercontrol
<Window x:Class="RadarStudio.Users"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Users" Height="300" Width="300">
<Grid >
<!--xmlns:ctrls="clr-namespace:RadarControls;assembly=RadarControls"
xmlns:vm='clr-namespace:RadarViewModel.Users;assembly=RadarViewModel'-->
<Grid Name="Dggrid"> </Grid>//New Grid is added as a place holder
</Grid>
</Window>
window code behind is as follows
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Collections.ObjectModel;
using RadarControls;
namespace RadarStudio
{
/// <summary>
/// Interaction logic for Users.xaml
/// </summary>
public partial class Users : Window
{
RadarDataGrid rg = new RadarDataGrid();//Object of user control
List<UserList> List = new List<UserList>();// It will be your item source
UserList ListItem;
public Users()
{
InitializeComponent();
//this.DataContext = this;
ListItem = new UserList();
ListItem.UserName = "dhaval";//Adding First Item
List.Add(ListItem);
ListItem = new UserList();
ListItem.UserName = "ravinder";//Adding Second
List.Add(ListItem);
rg.RadarGrid.ItemsSource = List;//Assigned Itemsource
Dggrid.Children.Add(rg);
}
}
/*This Class is need to store user information, you can include users additional details
(if needed) by creating corresponding Properties*/
public class UserList
{
string userName;
public string UserName
{
get { return userName; }
set { userName = value; }
}
}
}
Window has not Datacontext, and when your are binding str not found. Modify xaml :
<Window x:Class="RadarStudio.Users"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ctrls="clr-namespace:RadarControls;assembly=RadarControls"
xmlns:vm='clr-namespace:RadarViewModel.Users;assembly=RadarViewModel'
Title="Users" Height="300" Width="300"
Name="root">
<Grid >
<ctrls:RadarDataGrid Name="grid1" DataContext="{Binding Path=str, ElementName=root}"/>
</Grid> </Window>
And set str as Property
public partial class Users : Window
{
public Users()
{
str = new ObservableCollection<string>();
InitializeComponent();
//this.DataContext = this;
str.Add("dhaval");
str.Add("ravinder");
}
public ObservableCollection<string> str { get; set; }
}
This seems to be a silly mistake but when I initialized the observable collection before InitializeComponent call then it started to show the data.

How to fill Dictionary in ViewModel by values from TextBoxes in header of DataGrid

We need to resolve problem below.
In View We have defined DataGrid and DataTemplate which contains TextBox. DataTemplate is used for HeaderTemplate of DataGrid columns. Columns for DataGrid are added dynamically from code (not in code behind of View).
My question is:
I would like to fill Dictionary in ViewModel. That Dictionary would be contain Keys = DataGridTextColumn.Header (column name) and Values = TextBox.Text and should by filled continually when text in TextBox is changed.
How to do it?
Here is my code:
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:wpfToolkit="http://schemas.microsoft.com/wpf/2008/toolkit">
<Window.Resources>
<Style TargetType="DataGridColumnHeader">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</Window.Resources>
<Grid>
<DataGrid AutoGenerateColumns="False" HeadersVisibility="Column" HorizontalAlignment="Left" VerticalAlignment="Top" Loaded="Grid_Loaded">
<DataGrid.Resources>
<DataTemplate x:Key="HeaderDataTemplate">
<StackPanel Orientation="Vertical" >
<ContentControl Content="{Binding}" />
<TextBox x:Name="tbName"/>
</StackPanel>
</DataTemplate>
</DataGrid.Resources>
<DataGrid.Columns>
</DataGrid.Columns>
</DataGrid>
</Grid>
</Window>
MainWindow.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.ComponentModel;
namespace WpfApplication1
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.DataContext = new ViewModel();
}
private void Grid_Loaded(object sender, RoutedEventArgs e)
{
DataGrid grid = (DataGrid)sender;
ResourceDictionary resourecs = grid.Resources;
grid.Columns.Add(new DataGridTextColumn() { Header = "Column_1", Width = 150, HeaderTemplate = (DataTemplate)resourecs["HeaderDataTemplate"] });
grid.Columns.Add(new DataGridTextColumn() { Header = "Column_2", Width = 150, HeaderTemplate = (DataTemplate)resourecs["HeaderDataTemplate"] });
grid.Columns.Add(new DataGridTextColumn() { Header = "Column_N", Width = 150, HeaderTemplate = (DataTemplate)resourecs["HeaderDataTemplate"] });
}
}
public class ViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public IDictionary<string, string> HeaderTextValues
{
//Here is Dictionary, which should by filled by Key = DataGridTextColumn.Header, Value = TextBox.Text
get { return null; /*???? */ }
}
}
}

Categories