Hello all,
I am trying to create a configuration window that binds to an external XML file and implements two way binding in XAML. I have basically used the RadGridView demo as a starting point and have started to modify my code to implement the the two way binding piece, however I have hit a road block.
First off I am wondering whether I should use a DependencyObject or implement INotifiedProperty. At this point I am using a DependencyObject, however my textboxes do not appear to bind to the data, but the RadGridView does.
Basically I want to use the RadGridView as a list box on steroids and use the textboxes to edit/add records. However since this is an external xml file I am bit confused on what direction to take. Also I am using a ObservableCollection as my datasource, just as you do in the RadGridView demo, but I have also played around with using a XMLDataProvider. Any suggestions here?
Below are the basic classes I have so far.
Thanks for your help!
XAML
Dependency Object
Observable Collection
Datasource
External XML File
I am trying to create a configuration window that binds to an external XML file and implements two way binding in XAML. I have basically used the RadGridView demo as a starting point and have started to modify my code to implement the the two way binding piece, however I have hit a road block.
First off I am wondering whether I should use a DependencyObject or implement INotifiedProperty. At this point I am using a DependencyObject, however my textboxes do not appear to bind to the data, but the RadGridView does.
Basically I want to use the RadGridView as a list box on steroids and use the textboxes to edit/add records. However since this is an external xml file I am bit confused on what direction to take. Also I am using a ObservableCollection as my datasource, just as you do in the RadGridView demo, but I have also played around with using a XMLDataProvider. Any suggestions here?
Below are the basic classes I have so far.
Thanks for your help!
XAML
| <telerikNavigation:RadWindow x:Class="VistaAdmin.Configuration.Presentation.ConfigurationView" |
| 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:telerikSchema="http://schemas.telerik.com/2008/xaml/presentation" |
| xmlns:v="clr-namespace:VistaAdmin.Configuration.Presentation" |
| xmlns:p="clr-namespace:VistaAdmin.Configuration.Properties" |
| xmlns:db="clr-namespace:VistaAdmin.Configuration.Models" |
| xmlns:telerikGrid="clr-namespace:Telerik.Windows.Controls;assembly=Telerik.Windows.Controls.GridView" |
| xmlns:telerikNavigation="clr-namespace:Telerik.Windows.Controls;assembly=Telerik.Windows.Controls.Navigation" |
| xmlns:telerikRibbonBar="clr-namespace:Telerik.Windows.Controls;assembly=Telerik.Windows.Controls.RibbonBar" |
| xmlns:telerikInput="clr-namespace:Telerik.Windows.Controls;assembly=Telerik.Windows.Controls.Input" |
| xmlns:telerik="clr-namespace:Telerik.Windows.Controls;assembly=Telerik.Windows.Controls" |
| xmlns:xamlHelpers="clr-namespace:VistaAdmin.Configuration.Domain" |
| Header="{Binding HeaderInfo}" |
| mc:Ignorable="d" Height="420" Width="695" WindowStartupLocation="CenterOwner" |
| FontFamily="Calbri" ResizeMode="NoResize" telerik:StyleManager.Theme="{Binding Source={StaticResource settings}, Path=Default.Theme}"> |
| <telerikNavigation:RadWindow.Resources> |
| <!--<XmlDataProvider Source="DataSources\Environments.xml" x:Key="xmlData" XPath="/EnvironmentList" />--> |
| <db:XmlDataSource x:Key="xmlData" Source="Environments.xml"/> |
| </telerikNavigation:RadWindow.Resources> |
| <StackPanel> |
| <telerikNavigation:RadToolBar telerik:StyleManager.Theme="{Binding Source={StaticResource settings}, Path=Default.Theme}"> |
| <Button x:Name="configSaveButton" ToolTip="{x:Static p:Resources.Save}" Command="{Binding SaveConfigCommand}"> |
| <Image Source="../Resources/save.png" Width="16" Height="16"/> |
| </Button> |
| <Button x:Name="configValidateButton" ToolTip="{x:Static p:Resources.Validate}" Command="{Binding DBValidateCommand}"> |
| <Image Source="../Resources/db.png" Width="16" Height="16"/> |
| </Button> |
| </telerikNavigation:RadToolBar> |
| <Grid Height="Auto" > |
| <Grid.ColumnDefinitions> |
| <ColumnDefinition Width="250" MinWidth="180" /> |
| <ColumnDefinition Width="Auto" MinWidth="40" /> |
| <ColumnDefinition Width="*" MinWidth="180"/> |
| </Grid.ColumnDefinitions> |
| <Grid Grid.Column="0"> |
| <Grid.RowDefinitions> |
| <RowDefinition MinHeight="25"/> |
| <RowDefinition MinHeight="25"/> |
| <RowDefinition MinHeight="25"/> |
| <RowDefinition MinHeight="25"/> |
| <RowDefinition MinHeight="25"/> |
| <RowDefinition MinHeight="25"/> |
| <RowDefinition MinHeight="25"/> |
| <RowDefinition MinHeight="25"/> |
| <RowDefinition MinHeight="25"/> |
| <RowDefinition MinHeight="25"/> |
| <RowDefinition MinHeight="25"/> |
| <RowDefinition MinHeight="25"/> |
| <RowDefinition MinHeight="25"/> |
| <RowDefinition MinHeight="25"/> |
| </Grid.RowDefinitions> |
| <Label x:Name="labelName" Grid.Row="0" Margin="5,0,5,0"> |
| <TextBlock Text="Environment Name:" TextWrapping="Wrap" Foreground="Black" /> |
| </Label> |
| <TextBox Grid.Row="1" x:Name="textName" Margin="5,0,5,0" Text="{Binding Path=Name, Mode=TwoWay}" /> |
| <Label x:Name="labelServerName" Grid.Row="2" Margin="5,0,5,0"> |
| <TextBlock Text="DB Server Name:" TextWrapping="Wrap" Foreground="Black" /> |
| </Label> |
| <TextBox Grid.Row="3" x:Name="textServerName" Margin="5,0,5,0" Text="{Binding Path=Servername, Mode=TwoWay}"/> |
| <Label x:Name="labelUserName" Grid.Row="4" Margin="5,0,5,0"> |
| <TextBlock Text="User Name:" TextWrapping="Wrap" Foreground="Black" /> |
| </Label> |
| <TextBox Grid.Row="5" x:Name="textUserName" Margin="5,0,5,0" Text="{Binding Path=Username, Mode=TwoWay}"/> |
| <Label x:Name="labelPassword" Grid.Row="6" Margin="5,0,5,0"> |
| <TextBlock Text="Password:" TextWrapping="Wrap" HorizontalAlignment="Left" Foreground="Black" /> |
| </Label> |
| <PasswordBox Grid.Row="7" Margin="5,0,5,0" Name="textPassword" PasswordChar="*" |
| xamlHelpers:PasswordBoxAssistant.BindPassword="true" |
| xamlHelpers:PasswordBoxAssistant.BoundPassword="{Binding Path=Password, Mode=TwoWay}"/> |
| <Label x:Name="labelDBName" Grid.Row="8" Margin="5,0,5,0"> |
| <TextBlock Text="DB Name:" TextWrapping="Wrap" Foreground="Black" /> |
| </Label> |
| <TextBox Grid.Row="9" x:Name="textDBName" Margin="5,0,5,0" Text="{Binding Path=Databasename, Mode=TwoWay}"/> |
| <Label x:Name="labelServerType" Grid.Row="10" Margin="5,0,5,0"> |
| <TextBlock Text="DB Server Type:" TextWrapping="Wrap" Foreground="Black" /> |
| </Label> |
| <StackPanel Grid.Row="11" Orientation="Horizontal" Margin="5,0,5,0" HorizontalAlignment="Center" > |
| <telerik:RadRadioButton Width="80" Height="22" Margin="0 0 15 0" |
| HorizontalContentAlignment="Center" VerticalContentAlignment="Center" IsChecked="True" |
| telerik:StyleManager.Theme="{Binding Source={StaticResource settings}, Path=Default.Theme}" > |
| <telerik:RadRadioButton.Content> |
| <StackPanel Orientation="Horizontal" Margin="4 0"> |
| <TextBlock Text="SQL" Foreground="#2b2b2d" FontSize="12"/> |
| </StackPanel> |
| </telerik:RadRadioButton.Content> |
| </telerik:RadRadioButton> |
| <telerik:RadRadioButton Width="80" Height="22" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" |
| telerik:StyleManager.Theme="{Binding Source={StaticResource settings}, Path=Default.Theme}"> |
| <telerik:RadRadioButton.Content> |
| <StackPanel Orientation="Horizontal" Margin="4 0"> |
| <TextBlock Text="Oracle" Foreground="#2b2b2d" FontSize="12"/> |
| </StackPanel> |
| </telerik:RadRadioButton.Content> |
| </telerik:RadRadioButton> |
| </StackPanel> |
| <Label x:Name="labelRootPath" Grid.Row="12" Margin="5,0,5,0"> |
| <TextBlock Text="Root Path:" TextWrapping="Wrap" Foreground="Black" /> |
| </Label> |
| <StackPanel Grid.Row="13" Margin="5,0,5,0" Orientation="Horizontal"> |
| <TextBox x:Name="textPath" HorizontalAlignment="Left" Margin="0,0,5,0" Width="210" Text="{Binding Path=RootPath, Mode=TwoWay}"/> |
| <telerik:RadButton Width="25" HorizontalAlignment="Right" Command="{Binding BrowseCommand}" telerik:StyleManager.Theme="{Binding Source={StaticResource settings}, Path=Default.Theme}"> |
| <telerik:RadButton.Content> |
| <TextBlock Text="..." /> |
| </telerik:RadButton.Content> |
| </telerik:RadButton> |
| </StackPanel> |
| </Grid> |
| <Grid Grid.Column="1"> |
| <StackPanel VerticalAlignment="Center" Margin="5,0,5,0"> |
| <telerik:RadButton Width="85" Height="22" HorizontalContentAlignment="Left" VerticalContentAlignment="Center" |
| telerik:StyleManager.Theme="{Binding Source={StaticResource settings}, Path=Default.Theme}" Command="{Binding AddCommand}"> |
| <telerik:RadButton.Content> |
| <StackPanel Orientation="Horizontal" Margin="4,0,0,0" VerticalAlignment="Center"> |
| <Image Source="../Resources/Add.png" Width="16" Height="16" /> |
| <TextBlock Text="Add" Foreground="#2b2b2d" FontSize="12" Margin="9 0 0 0"/> |
| </StackPanel> |
| </telerik:RadButton.Content> |
| </telerik:RadButton> |
| <telerik:RadButton Width="85" Height="22" HorizontalContentAlignment="Left" VerticalContentAlignment="Center" Margin="0,5,0,0" Command="{Binding RemoveCommand}" |
| telerik:StyleManager.Theme="{Binding Source={StaticResource settings}, Path=Default.Theme}"> |
| <telerik:RadButton.Content> |
| <StackPanel Orientation="Horizontal" Margin="4,0,0,0" VerticalAlignment="Center"> |
| <Image Source="../Resources/Delete.png" Width="16" Height="16" /> |
| <TextBlock Text="Remove" Foreground="#2b2b2d" FontSize="12" Margin="9 0"/> |
| </StackPanel> |
| </telerik:RadButton.Content> |
| </telerik:RadButton> |
| </StackPanel> |
| </Grid> |
| <telerikGrid:RadGridView Grid.Column="2" Height="Auto" Name="gridEnvironments" Width="Auto" ItemsSource="{Binding Source={StaticResource xmlData}}" telerik:StyleManager.Theme="{Binding Source={StaticResource settings}, Path=Default.Theme}"/> |
| </Grid> |
| </StackPanel> |
| </telerikNavigation:RadWindow> |
Dependency Object
| using System; |
| using System.Collections.Generic; |
| using System.Linq; |
| using System.Text; |
| using System.Xml; |
| using System.Windows; |
| using System.Xml.Serialization; |
| namespace VistaAdmin.Configuration.Models |
| { |
| public class Environment : DependencyObject |
| { |
| #region DependencyProperties |
| public static readonly DependencyProperty ServernameProperty = |
| DependencyProperty.Register("Servername", typeof(String), typeof(Environment)); |
| public static readonly DependencyProperty NameProperty = |
| DependencyProperty.Register("Name", typeof(String), typeof(Environment)); |
| public static readonly DependencyProperty DatabasenameProperty = |
| DependencyProperty.Register("Databasename", typeof(String), typeof(Environment)); |
| public static readonly DependencyProperty UsernameProperty = |
| DependencyProperty.Register("Username", typeof(String), typeof(Environment)); |
| public static readonly DependencyProperty PasswordProperty = |
| DependencyProperty.Register("Password", typeof(String), typeof(Environment)); |
| public static readonly DependencyProperty ServerTypeProperty = |
| DependencyProperty.Register("ServerType", typeof(String), typeof(Environment)); |
| public static readonly DependencyProperty RootPathProperty = |
| DependencyProperty.Register("RootPath", typeof(String), typeof(Environment)); |
| #endregion |
| #region IEnvironment Members |
| [XmlAttribute(AttributeName = "Servername")] |
| public string Servername |
| { |
| get {return (string)GetValue(ServernameProperty);} |
| set {SetValue(ServernameProperty,value);} |
| } |
| [XmlAttribute(AttributeName = "Name")] |
| public string Name |
| { |
| get {return (string)GetValue(NameProperty);} |
| set {SetValue(NameProperty,value);} |
| } |
| [XmlAttribute(AttributeName = "Databasename")] |
| public string Databasename |
| { |
| get {return (string)GetValue(DatabasenameProperty);} |
| set {SetValue(DatabasenameProperty,value);} |
| } |
| [XmlAttribute(AttributeName = "Username")] |
| public string Username |
| { |
| get {return (string)GetValue(UsernameProperty);} |
| set {SetValue(UsernameProperty,value);} |
| } |
| [XmlAttribute(AttributeName = "Password")] |
| public string Password |
| { |
| get {return (string)GetValue(PasswordProperty);} |
| set {SetValue(PasswordProperty,value);} |
| } |
| [XmlAttribute(AttributeName = "ServerType")] |
| public string ServerType |
| { |
| get {return (string)GetValue(ServerTypeProperty);} |
| set {SetValue(ServerTypeProperty,value);} |
| } |
| [XmlAttribute(AttributeName = "RootPath")] |
| public string RootPath |
| { |
| get {return (string)GetValue(RootPathProperty);} |
| set {SetValue(RootPathProperty,value);} |
| } |
| #endregion |
| } |
| } |
Observable Collection
| using System; |
| using System.Collections.Generic; |
| using System.Collections.ObjectModel; |
| using System.Linq; |
| using System.Text; |
| using System.Xml; |
| using System.Xml.Serialization; |
| namespace VistaAdmin.Configuration.Models |
| { |
| [XmlRoot(ElementName = "EnvironmentList")] |
| public class EnvironmentsList : ObservableCollection<Environment> |
| { |
| public void AddRange(IEnumerable<Environment> range) |
| { |
| foreach (Environment node in range) |
| { |
| this.Add(node); |
| } |
| } |
| //public void Add(Environment node) |
| //{ |
| // this.Add(node); |
| //} |
| } |
| } |
Datasource
| using System; |
| using System.Reflection; |
| using System.Collections.Generic; |
| using System.Collections.ObjectModel; |
| using System.Linq; |
| using System.Text; |
| using System.Xml; |
| using System.Xml.Serialization; |
| using System.Xml.XPath; |
| using System.IO; |
| using System.Windows.Data; |
| using System.ComponentModel; |
| using Microsoft.Practices.EnterpriseLibrary.Logging; |
| namespace VistaAdmin.Configuration.Models |
| { |
| public class XmlDataSource : EnvironmentsList |
| { |
| private string source; |
| public string Source |
| { |
| get |
| { |
| return this.source; |
| } |
| set |
| { |
| try |
| { |
| Assembly executingAssembly = Assembly.GetExecutingAssembly(); |
| string xmlFile = Path.GetDirectoryName(executingAssembly.Location) + @"\DataSources\" + value; |
| this.source = xmlFile; |
| AddRange(RetrieveData(File.Open(xmlFile, FileMode.Open))); |
| } |
| catch (Exception ex) |
| { |
| Log("Error occured retrieving data:" + ex.Message, System.Diagnostics.TraceEventType.Error); |
| } |
| } |
| } |
| private EnvironmentsList RetrieveData(Stream xmlStream) |
| { |
| XmlSerializer serializer = new XmlSerializer(typeof(EnvironmentsList)); |
| StreamReader reader = new StreamReader(xmlStream); |
| EnvironmentsList list = (EnvironmentsList)serializer.Deserialize(reader); |
| return list; |
| } |
| private static void Log(string message, System.Diagnostics.TraceEventType severity) |
| { |
| LogEntry entry = new LogEntry(); |
| entry.Severity = severity; |
| entry.Message = message; |
| entry.Title = "VistaAdminConfiguration"; |
| entry.Categories.Add("Configuration"); |
| Logger.Write(entry); |
| } |
| public static void SaveData(Environment environment) |
| { |
| try |
| { |
| Assembly executingAssembly = Assembly.GetExecutingAssembly(); |
| string xmlFile = Path.GetDirectoryName(executingAssembly.Location) + @"\DataSources\Environments.xml"; |
| XmlSerializer serializer = new XmlSerializer(typeof(EnvironmentsList)); |
| StreamWriter writer = new StreamWriter(xmlFile); |
| serializer.Serialize(writer, environment); |
| } |
| catch (Exception ex) |
| { |
| Log("Error trying to save Enviroment: " + ex.Message, System.Diagnostics.TraceEventType.Error); |
| } |
| } |
| } |
| } |
External XML File
| <?xml version="1.0" encoding="utf-8" ?> |
| <EnvironmentList> |
| <Environment Name="Environment Name" Servername="Server" Username="sa" Password="!@#!@$!@%#" Databasename="DatabaseName" ServerType="SQL" RootPath="C:\Temp"/> |
| </EnvironmentList> |