My name is Edward Tanguay. I'm an American software and web developer living and working in Berlin, Germany.


2 days ago: Posted new ObservableCollection MenuItem w/ TextBox, ItemContainerStyle, still doesn't work, but now in a different way: http://is.gd/1l58e.
2 days ago: Has anyone doing WPF successfully bound MenuItems to an ObservableCollection, looking for a working code example: http://is.gd/1l58e.
2 days ago: Video: what if JFK had been a CEO, speaker is my former roommate from college, lucid and entertaining as back in the day: http://is.gd/1l4fl.
3 days ago: Informative podcast on sharepoint with Sahil Malik, requires AD?, must run in VM?, no debugging? sounds cumbersome: http://is.gd/1jFz1.
4 days ago: Got SQLite installed and running on Debian VPS, here's how: http://is.gd/1iL68.
4 days ago: Purchased and set up a VPS within an hour on a Sunday afternoon, nice experience so far: http://www.server4you.de.
4 days ago: Podcast by Kevin Kelly on the future of the web, "cloud applications, all about data, wholly different than today's web": http://is.gd/1iKtr.
4 days ago: Enjoyable, 2-beer podcast, @shanselman, Franklin et al. get rolling, funny, pub-atmosphere geek talk, win7, surface, etc. http://is.gd/1iKbP.
4 days ago: If you compose music, check out: http://www.ableton.com, good example of a simple and effective product demo video, 12 min. riveting.
5 days ago: Anyone know how I can post-install SQLite on a Suse VPS with automatic Apache/PHP setup? http://is.gd/1hm6X.
on Wednesday, June 24, 2009: C# CODE EXAMPLE: Three ways to create the same XML file (string concat, xmlwriter, linq-to-xml): http://is.gd/1ctco.
Four ways to create an XML file Here are four ways to create the same XML string that I needed for an application: string concatenation, XmlWriter, LINQ-to-XML, in reverse order of preference (plus an example using XML literals which Jim Wooley posted on his site along with some notes on the dangers of string concatenation). These code samples assume an object called DataType which is not included in the code, so the code isn't executable as is, but I just wanted to record the syntax of each way for further reference. Notice the Enumerable.Range(1, 3).Select on the LINQ-to-XML functions as a for loop. String Concatentation:
StringBuilder sb = new StringBuilder();
sb.Append("<?xml version=\"1.0\" encoding=\"utf-8\"?>" + Environment.NewLine); sb.Append(String.Format("<{0}>{1}", _pluralCamelNotation, Environment.NewLine)); for (int index = 0; index < 3; index++) { sb.Append(String.Format("\t<{0}>{1}", _singularCamelNotation, Environment.NewLine)); foreach (DataType dataType in _allDataTypes) { sb.Append(String.Format("\t\t<{0}>{2}</{0}>{1}", dataType.CamelCaseNotation, Environment.NewLine, dataType.GetDummyData())); } sb.Append(String.Format("\t</{0}>{1}", _singularCamelNotation, Environment.NewLine)); } sb.Append(String.Format("</{0}>{1}", _pluralCamelNotation, Environment.NewLine)); XmlWriter:
XmlWriterSettings settings = new XmlWriterSettings();
settings.NewLineHandling = NewLineHandling.Entitize; settings.Indent = true; settings.IndentChars = "\t"; StringBuilder sb = new StringBuilder(); using (XmlWriter xw = XmlWriter.Create(sb, settings)) { xw.WriteStartDocument(); xw.WriteStartElement(_pluralCamelNotation); for (int i = 0; i < 3; i++) { xw.WriteStartElement(_singularCamelNotation); foreach (DataType dataType in _allDataTypes) { xw.WriteElementString(dataType.CamelCaseNotation, dataType.GetDummyData()); } xw.WriteEndElement(); } xw.WriteEndElement(); xw.WriteEndDocument(); xw.Close(); } return sb.ToString(); XML Literals (VB.NET):
Dim doc = <?xml version="1.0"?>
<<%= _pluralCamelNotation %>> <%= From i In Enumerable.Range(1, 3) _ Select <<%= _singluarNotation %>> <%= From t In _allDataTypes _ Select <<%= t.CamelCaseNotation %>> <%= t.GetDummyData %></> %> </> %> </> LINQ-to-XML:
XDocument doc = new XDocument( new XDeclaration("1.0", null, null), new XElement(_pluralCamelNotation, Enumerable.Range(1, 3).Select( i => new XElement(_singularCamelNotation, _allDataTypes.Select( dataType => new XElement( dataType.CamelCaseNotation, dataType.GetDummyData()) ) )))); return doc.ToString(); post comment |
WPF/MVVM application with dynamic menu and buttons This is a base WPF application with a View/ViewModel pattern and no code-behind, it loads the pages from an XML file. To create a new page you need to make a new entry in the XML, create a View and a ViewModel and it will automatically appear. The MainView is injected into each ViewModel so that each ViewModel can have buttons which go to other pages, there is an example of this on the Options page. ![]() > > > Download Code MainView.xaml:
<Window x:Class="TestMenu234.Views.MainView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:c="clr-namespace:TestMenu234.Commands" xmlns:vm="clr-namespace:TestMenu234.ViewModels" xmlns:v="clr-namespace:TestMenu234.Views" xmlns:converters="clr-namespace:TestMenu234.Converters" Title="Main Window" Height="400" Width="630" MinWidth="630"> <Window.Resources> <DataTemplate x:Key="CodeGenerationMenuTemplate"> <MenuItem Header="{Binding Title}" Command="{Binding DataContext.SwitchPageCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Menu}}}" CommandParameter="{Binding IdCode}"/> </DataTemplate> <converters:PageItemViewAndViewModelMatcher x:Key="PageItemViewAndViewModelMatcher"/> <DataTemplate DataType="{x:Type vm:ViewModelPageItemBase}"> <ContentControl Content="{Binding Converter={StaticResource PageItemViewAndViewModelMatcher}}"/> </DataTemplate> </Window.Resources> <DockPanel LastChildFill="True"> <Menu DockPanel.Dock="Top"> <MenuItem Header="Pages" ItemsSource="{Binding AllPageItemViewModels}" ItemTemplate="{StaticResource CodeGenerationMenuTemplate}"/> </Menu> <Border DockPanel.Dock="Bottom" Padding="5 5 5 0" Background="#eee"> <Grid Background="#eee"> <Grid.ColumnDefinitions> <ColumnDefinition Width="*" MinWidth="300"/> <ColumnDefinition Width="200"/> <ColumnDefinition Width="100"/> </Grid.ColumnDefinitions> <Slider Grid.Column="0" HorizontalAlignment="Left" Value="{Binding CurrentPageItemViewModelIndex}" Width="300" Minimum="0" Maximum="{Binding HighestPageItemIndex}"/> <TextBlock Grid.Column="1" HorizontalAlignment="Center" FontWeight="Bold" Text="{Binding CurrentPageItemViewModelTitle}"/> <DockPanel Grid.Column="2" Margin="0 0 0 5" LastChildFill="False"> <Button Margin="3 0 0 0" DockPanel.Dock="Right" HorizontalAlignment="Right" Content="Next" Command="{Binding NextPageCommand}"/> <Button DockPanel.Dock="Right" Content="Prev" Command="{Binding PreviousPageCommand}"/> </DockPanel> </Grid> </Border> <ContentControl DockPanel.Dock="Top" VerticalAlignment="Stretch" VerticalContentAlignment="Stretch" Content="{Binding CurrentPageItemViewModel}"/> </DockPanel> </Window> MainViewModel constructor:
public MainViewModel()
{ PageItems pageItems = PageItems.Create("all"); foreach (PageItem pageItem in pageItems.Collection) { string assemblyName = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name; string viewModelName = assemblyName + ".ViewModels.PageItem" + StringHelpers.ForcePascalNotation(pageItem.IdCode) + "ViewModel"; var type = Type.GetType(viewModelName); var viewModel = Activator.CreateInstance(type, this, pageItem) as ViewModelPageItemBase; AllPageItemViewModels.Add(viewModel); } CurrentPageItemViewModelIndex = 0; LoadCurrentPageItemViewModel(); } post comment |
How to create a WPF/MVVM application with dynamic menu This application loads an XML file of "PageItems" which fill an ObservableCollection in the MainViewModel which builds a Menu dynamically. The user can also change the pages with a slider or by clicking the previous and next buttons. The title of the page is displayed at the bottom as well. For some reason when the user clicks on the icon area of the menu item, the DelegateCommand is not fired. I asked about the menu item issue on StackOverflow. ![]() > > > Download Code MainView.xaml:
<Window x:Class="TestMenu234.Views.MainView" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:c="clr-namespace:TestMenu234.Commands" xmlns:vm="clr-namespace:TestMenu234.ViewModels" xmlns:v="clr-namespace:TestMenu234.Views" Title="Main Window" Height="400" Width="630" MinWidth="630"> <Window.Resources> <DataTemplate x:Key="CodeGenerationMenuTemplate"> <MenuItem Header="{Binding Title}" Command="{Binding DataContext.SwitchPageCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Menu}}}" CommandParameter="{Binding IdCode}"/> </DataTemplate> <DataTemplate DataType="{x:Type vm:PageItemManageCustomersViewModel}"> <v:PageItemManageCustomersView/> </DataTemplate> <DataTemplate DataType="{x:Type vm:PageItemManageEmployeesViewModel}"> <v:PageItemManageEmployeesView/> </DataTemplate> <DataTemplate DataType="{x:Type vm:PageItemReportsViewModel}"> <v:PageItemReportsView/> </DataTemplate> <DataTemplate DataType="{x:Type vm:PageItemOptionsViewModel}"> <v:PageItemOptionsView/> </DataTemplate> </Window.Resources> <DockPanel LastChildFill="False"> <Menu DockPanel.Dock="Top"> <MenuItem Header="Pages" ItemsSource="{Binding AllPageViewModels}" ItemTemplate="{StaticResource CodeGenerationMenuTemplate}"/> </Menu> <ContentControl DockPanel.Dock="Top" Content="{Binding CurrentPageItemViewModel}"/> <Border DockPanel.Dock="Bottom" Padding="5 5 5 0" Background="#eee"> <Grid Background="#eee"> <Grid.ColumnDefinitions> <ColumnDefinition Width="*" MinWidth="300"/> <ColumnDefinition Width="200"/> <ColumnDefinition Width="100"/> </Grid.ColumnDefinitions> <Slider Grid.Column="0" HorizontalAlignment="Left" Value="{Binding CurrentPageItemViewModelIndex}" Width="300" Minimum="0" Maximum="{Binding HighestPageItemIndex}"/> <TextBlock Grid.Column="1" HorizontalAlignment="Center" FontWeight="Bold" Text="{Binding CurrentPageItemViewModelTitle}"/> <DockPanel Grid.Column="2" Margin="0 0 0 5" LastChildFill="False"> <Button Margin="3 0 0 0" DockPanel.Dock="Right" HorizontalAlignment="Right" Content="Next" Command="{Binding NextPageCommand}"/> <Button DockPanel.Dock="Right" Content="Prev" Command="{Binding PreviousPageCommand}"/> </DockPanel> </Grid> </Border> </DockPanel> </Window> post comment |
How to use MVVM pattern to validate an e-mail field as the user types Most books would show you how to validate a field as the user is typing by creating a TextBox then adding a TextChanged event and handling that event in the code behind, or using a Validator class. However, if you are using the MVVM pattern, you can basically forget this since you don't want your code-behind side-stepping your ViewModel to get information from the database, etc. Instead, you need to bind the text of your TextBox to a property on your ViewModel like this Text="{Binding FieldEmail, UpdateSourceTrigger=PropertyChanged}"> and then attach a style to the TextBox which has DataTriggers that change the color based on another property on your ViewModel. This works well, is fully MVVM compliant, no code-behind. ![]() > > > Download Code XAML:
<Window x:Class="TestUpdateText.Views.MainView" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:c="clr-namespace:TestUpdateText.Commands" Title="Main Window" Height="400" Width="800"> <Window.Resources> <Style x:Key="FieldEmailStyle" TargetType="TextBox"> <Style.Triggers> <DataTrigger Binding="{Binding FieldEmailValidationStatus}" Value="invalid"> <Setter Property="TextBox.Background" Value="Yellow"/> </DataTrigger> <DataTrigger Binding="{Binding FieldEmailValidationStatus}" Value="valid"> <Setter Property="TextBox.Background" Value="LightGreen"/> </DataTrigger> </Style.Triggers> </Style> </Window.Resources> <DockPanel HorizontalAlignment="Left" LastChildFill="False" Margin="10"> <StackPanel Orientation="Horizontal" HorizontalAlignment="Left" DockPanel.Dock="Top"> <TextBlock FontSize="14" Text="E-Mail: " Margin="0 0 5 0"/> <TextBox Width="200" Style="{StaticResource FieldEmailStyle}" Text="{Binding FieldEmail, UpdateSourceTrigger=PropertyChanged}"> </TextBox> <TextBlock FontSize="14" Text="{Binding FieldEmailMessage}" Margin="5 0 0 0"/> </StackPanel> </DockPanel> </Window> post comment |
How to bind multiple XAML controls to one ObservableCollection in your ViewModel This was an experiment to get control of how to bind various controls (ComboBox, ListBox, Slider) to one ObservableCollection (Customers) in the ViewModel. You can also add a new Customer by typing in a first and last name and only when both are filled out will the button be enabled. There is no code-behind in this example, all is being done with binding. When you move one control all others move as well. ![]() > > > Download Code XAML:
<Window x:Class="TestSelectedItem234.Views.MainView" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:c="clr-namespace:TestSelectedItem234.Commands" Title="Main Window" Height="600" Width="800"> <Window.Resources> <DataTemplate x:Key="CustomerShowTemplate"> <Border CornerRadius="5" Background="#eee" Padding="5" HorizontalAlignment="Left"> <StackPanel> <StackPanel Orientation="Horizontal"> <TextBlock FontSize="14" FontWeight="Bold" Text="{Binding FirstName}"/> <TextBlock Text=" "/> <TextBlock FontSize="14" FontWeight="Bold" Text="{Binding LastName}"/> </StackPanel> <TextBlock Text="{Binding Path=HireDate, StringFormat='Hired on {0:MMM dd, yyyy}'}"/> </StackPanel> </Border> </DataTemplate> <DataTemplate x:Key="CustomerComboBoxTemplate"> <StackPanel Orientation="Horizontal"> <TextBlock Text="{Binding FirstName}"/> <TextBlock Text=" "/> <TextBlock Text="{Binding LastName}"/> </StackPanel> </DataTemplate> <DataTemplate x:Key="CustomerItemTemplate"> <Border Background="#fff" Padding="2" > <Border CornerRadius="5" Width="400"> <Border.Background> <LinearGradientBrush EndPoint="1.074,2.256" StartPoint="-0.182,-0.829"> <GradientStop Color="#FFCAA157" Offset="0"/> <GradientStop Color="#FFE5C68D" Offset="1"/> </LinearGradientBrush> </Border.Background> <StackPanel> <TextBlock Margin="5" Foreground="#555"> <TextBlock.Text> <MultiBinding StringFormat="{}{0} {1}"> <Binding Path="FirstName"/> <Binding Path="LastName"/> </MultiBinding> </TextBlock.Text> </TextBlock> </StackPanel> </Border> </Border> </DataTemplate> <DataTemplate x:Key="CustomerItemTemplateSelected"> <Border Background="#fff" Padding="2" > <Border CornerRadius="5" Width="400"> <Border.Background> <LinearGradientBrush EndPoint="0.09,1.066" StartPoint="0.89,-0.531"> <GradientStop Color="#FFFBCE29" Offset="1"/> <GradientStop Color="#FFE5A646" Offset="0"/> </LinearGradientBrush> </Border.Background> <StackPanel> <TextBlock FontSize="18" Margin="10 5 10 5" Foreground="#000"> <TextBlock.Text> <MultiBinding StringFormat="{}{0} {1}"> <Binding Path="FirstName"/> <Binding Path="LastName"/> </MultiBinding> </TextBlock.Text> </TextBlock> <TextBlock Margin="10 0 10 8" Foreground="#000"> <TextBlock.Text> <Binding Path="HireDate" StringFormat="{}Hired on {0:MMM dd, yyyy}"/> </TextBlock.Text> </TextBlock> </StackPanel> </Border> </Border> </DataTemplate> <Style TargetType="{x:Type ListBoxItem}" x:Key="CustomerItemContainerStyle"> <Setter Property="ContentTemplate" Value="{StaticResource CustomerItemTemplate}" /> <Setter Property="Padding" Value="0"/> <Setter Property="Margin" Value="0" /> <Style.Triggers> <Trigger Property="IsSelected" Value="True"> <Setter Property="ContentTemplate" Value="{StaticResource CustomerItemTemplateSelected}" /> </Trigger> </Style.Triggers> </Style> </Window.Resources> <ScrollViewer> <DockPanel LastChildFill="False" Margin="10"> <ContentControl DockPanel.Dock="Top" Margin="0 0 0 10" Content="{Binding SelectedCustomer}" ContentTemplate="{StaticResource CustomerShowTemplate}"/> <StackPanel HorizontalAlignment="Left" DockPanel.Dock="Top" Margin="0 0 0 10"> <ComboBox ItemsSource="{Binding Customers}" ItemTemplate="{StaticResource CustomerComboBoxTemplate}" Margin="10" HorizontalAlignment="Left" SelectedItem="{Binding SelectedCustomer, Mode=TwoWay}"/> <Slider Minimum="0" Margin="10" Width="400" IsSnapToTickEnabled="True" Maximum="{Binding HighestCustomerIndex, Mode=TwoWay}" Value="{Binding SelectedCustomerIndex, Mode=TwoWay}"/> <StackPanel Orientation="Horizontal" Margin="10"> <TextBlock Text="Type in a new customer name: " FontSize="14"/> <TextBox Width="150" Text="{Binding NewFirstName}"/> <TextBlock Text=" "/> <TextBox Width="150" Text="{Binding NewLastName}"/> <TextBlock Text=" "/> <Button Width="150" HorizontalAlignment="Left" Content="Add Customer" Command="{Binding AddCustomerCommand}"/> </StackPanel> <ListBox HorizontalAlignment="Left" ItemsSource="{Binding Customers, Mode=TwoWay}" ItemContainerStyle="{StaticResource CustomerItemContainerStyle}" SelectedItem="{Binding SelectedCustomer, Mode=TwoWay}"/> </StackPanel> </DockPanel> </ScrollViewer> </Window> post comment |
Three ways to format dates in a XAML DataTemplate Just wanted to record these three ways of formatting dates, basically you can use StringFormat in the same way you do in code in this way, also see my example of MultiBinding which uses StringFormat. ![]()
<Window x:Class="TestSelectedItem234.Views.MainView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:c="clr-namespace:TestSelectedItem234.Commands" Title="Main Window" Height="400" Width="800"> <Window.Resources> <DataTemplate x:Key="CustomerShowTemplate"> <Border CornerRadius="5" Background="#eee" Padding="5" HorizontalAlignment="Left" Width="200"> <StackPanel> <StackPanel Orientation="Horizontal"> <TextBlock FontSize="14" FontWeight="Bold" Text="{Binding FirstName}"/> <TextBlock Text=" "/> <TextBlock FontSize="14" FontWeight="Bold" Text="{Binding LastName}"/> </StackPanel> <TextBlock Text="{Binding Path=HireDate, StringFormat='MMM dd, yyyy'}"/> <TextBlock Text="{Binding Path=HireDate, StringFormat='Hired on {0}'}"/> <TextBlock Text="{Binding Path=HireDate, StringFormat='Hired on {0:MMM dd, yyyy}'}"/> </StackPanel> </Border> </DataTemplate> </Window.Resources> <DockPanel LastChildFill="False" Margin="10"> <ContentControl DockPanel.Dock="Top" Margin="0 0 0 10" Content="{Binding SelectedCustomer}" ContentTemplate="{StaticResource CustomerShowTemplate}"/> </DockPanel> </Window> post comment |
How to access objects and their properties within Observable collections This was an experiment to find the syntax to access e.g. a particular property of a particular customer within a collection and determine some UI effect based on the value. Notice you get the Status of the first customer object with this: {Binding Customers[0].Status}. ![]() > > > Download Code View:
<Window x:Class="TestMvvmProperties8383.Views.MainView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:c="clr-namespace:TestMvvmProperties8383.Commands" Title="Main Window" Height="400" Width="800"> <Window.Resources> <Style x:Key="MainMessage" TargetType="TextBlock"> <Style.Triggers> <DataTrigger Binding="{Binding Customers[0].Status}" Value="approved"> <Setter Property="Text" Value="First customer is approved"/> <Setter Property="Background" Value="LightGreen"/> </DataTrigger> <DataTrigger Binding="{Binding Customers[0].Status}" Value="waiting"> <Setter Property="Text" Value="First customer is waiting"/> <Setter Property="Background" Value="Yellow"/> </DataTrigger> </Style.Triggers> </Style> <DataTemplate x:Key="MainTemplate"> <Border CornerRadius="5" Background="Orange" Padding="5" Margin="2"> <StackPanel Orientation="Horizontal"> <TextBlock Text="{Binding FirstName}"/> <TextBlock Text=" "/> <TextBlock Text="{Binding LastName}"/> <TextBlock Text=": "/> <TextBlock Text="{Binding Status}"/> </StackPanel> </Border> </DataTemplate> </Window.Resources> <DockPanel HorizontalAlignment="Left" LastChildFill="False" Margin="10"> <TextBlock DockPanel.Dock="Top" Margin="10" Style="{StaticResource MainMessage}"/> <ItemsControl Margin="10" DockPanel.Dock="Top" ItemsSource="{Binding Customers}" ItemTemplate="{StaticResource MainTemplate}"/> <StackPanel DockPanel.Dock="Top" Orientation="Horizontal" Margin="10"> <Button Content="Sort Order 1" Command="{Binding SortOrder1Command}" Margin="5"/> <Button Content="Sort Order 2" Command="{Binding SortOrder2Command}" Margin="5"/> </StackPanel> </DockPanel> </Window> ViewModel:
public MainViewModel()
{ LoadCustomers(1); } private void LoadCustomers(int sortOrder) { Customers.Clear(); if (sortOrder == 1) { Customers.Add(new Customer { FirstName = "Jim", LastName = "Smith", Status = "waiting" }); Customers.Add(new Customer { FirstName = "Joe", LastName = "Jones", Status = "waiting" }); Customers.Add(new Customer { FirstName = "Jack", LastName = "Alard", Status = "approved" }); } else { Customers.Add(new Customer { FirstName = "Jack", LastName = "Alard", Status = "approved" }); Customers.Add(new Customer { FirstName = "Jim", LastName = "Smith", Status = "waiting" }); Customers.Add(new Customer { FirstName = "Joe", LastName = "Jones", Status = "waiting" }); } } post comment |
How to access bound individual items in ObservableCollection from XAML This shows an example of an instant translator for an application: a user can use a slider to switch between English and German whereby he instantly sees the text on every control be translated. Collection elements such as ListView are straight-forward and for single elements such as Button and TextBlock the syntax for accessing the desired object is {Binding Translations[0].Value} where "Value" can be any property on the object in the ObservableCollection. ![]() > > > Download Code XAML:
<Window x:Class="TestObjectUpdate234.Views.MainView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:c="clr-namespace:TestObjectUpdate234.Commands" Title="Main Window" Height="250" Width="600"> <Window.Resources> <DataTemplate x:Key="ShowTemplate"> <TextBlock Text="{Binding Value}"/> </DataTemplate> </Window.Resources> <DockPanel LastChildFill="False" Margin="10"> <Button DockPanel.Dock="Top" Content="{Binding Translations[0].Value}" Width="150" Margin="5" HorizontalAlignment="Left"/> <TextBlock DockPanel.Dock="Top" Margin="5" Text="{Binding Translations[1].Value}" /> <ListView DockPanel.Dock="Top" ItemsSource="{Binding Translations}" Margin="5" ItemTemplate="{StaticResource ShowTemplate}"/> <StackPanel DockPanel.Dock="Bottom" Orientation="Horizontal" Margin="0 20 0 0"> <TextBlock Text="English" Margin="0 0 5 0"/> <Slider Name="TheLanguageIndexSlider" Minimum="0" Maximum="1" IsSnapToTickEnabled="True" Width="100" Margin="5" Value="{Binding LanguageIndex}" HorizontalAlignment="Left"/> <TextBlock Text="German" Margin="5 0 0 0"/> </StackPanel> </DockPanel> </Window> ViewModel:
using System.Collections.Generic;
using System.Collections.ObjectModel; using TestObjectUpdate234.Models; namespace TestObjectUpdate234.ViewModels { public class MainViewModel : ViewModelBase { private ObservableCollection<TranslateTerm> _translations = new ObservableCollection<TranslateTerm>(); public ObservableCollection<TranslateTerm> Translations { get { return _translations; } set { _translations = value; OnPropertyChanged("Translations"); } } private int _languageIndex; public int LanguageIndex { get { return _languageIndex; } set { _languageIndex = value; OnPropertyChanged("LanguageIndex"); FillTranslations(); } } public MainViewModel() { _languageIndex = 0; //english FillTranslations(); } private void FillTranslations() { if (_languageIndex == 0) { Translations.Clear(); Translations.Add(new TranslateTerm { Key = "add", Value = "Add"}); Translations.Add(new TranslateTerm { Key = "copy", Value = "Copy" }); } else { Translations.Clear(); Translations.Add(new TranslateTerm { Key = "add", Value = "Hinzufügen" }); Translations.Add(new TranslateTerm { Key = "copy", Value = "Kopieren" }); } } } } TranslateTerm.cs:
namespace TestObjectUpdate234.Models
{ public class TranslateTerm { public string Key { get; set; } public string Value { get; set; } } } post comment |
How to access items in a (readonly) ViewModel Dictionary property This example shows how you can have a ViewModel property that is a Dictionary of saw 200 items and in your view you can access each one with simple square bracket syntax. Unfortunately the Dictionary object is not updated as are string properties as this example shows. So this is a good solution if you need a readonly Dictionary that does not need to be further updated at runtime. For that, you would need to create an ObservableDictionary or find some syntax like this which allows you to access items in an ObservableCollection in the same way as you access them in a Dictionary. ![]() > > > Download Code XAML:
<Window x:Class="TestObjectUpdate234.Views.MainView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:c="clr-namespace:TestObjectUpdate234.Commands" Title="Main Window" Height="400" Width="800"> <StackPanel Margin="10"> <TextBlock Text="{Binding TranslationEdit}" /> <TextBlock Text="{Binding Translations[add]}" /> <StackPanel DockPanel.Dock="Bottom" Orientation="Horizontal" Margin="0 20 0 0"> <TextBlock Text="English" Margin="0 0 5 0"/> <Slider Name="TheLanguageIndexSlider" Minimum="0" Maximum="1" IsSnapToTickEnabled="True" Width="100" Margin="5" Value="{Binding LanguageIndex}" HorizontalAlignment="Left"/> <TextBlock Text="German" Margin="5 0 0 0"/> </StackPanel> </StackPanel> </Window> ViewModel:
using System.Collections.Generic;
namespace TestObjectUpdate234.ViewModels { public class MainViewModel : ViewModelBase { private string _translationEdit; public string TranslationEdit { get { return _translationEdit; } set { _translationEdit = value; OnPropertyChanged("TranslationEdit"); } } private Dictionary<string, string> _translations = new Dictionary<string, string>(); public Dictionary<string, string> Translations { get { return _translations; } set { _translations = value; OnPropertyChanged("Translations"); } } private int _languageIndex; public int LanguageIndex { get { return _languageIndex; } set { _languageIndex = value; OnPropertyChanged("LanguageIndex"); FillTranslations(); } } public MainViewModel() { _languageIndex = 0; //english FillTranslations(); } private void FillTranslations() { if (_languageIndex == 0) { TranslationEdit = "Edit"; Translations.Clear(); Translations.Add("add", "Add"); } else { TranslationEdit = "Bearbeiten"; Translations.Clear(); Translations.Add("add", "Hinzufügen"); } } } } post comment |
How to get and set properties of an object dynamically with reflection These two methods can be used on on object so that you can e.g. parse an XML file that has changes in it, and make changes on an object based on the strings in the XML file. ![]()
using System;
using System.Reflection; namespace TestSetPropertyValue834 { class Program { static void Main(string[] args) { Customer customer = new Customer { Id = 1, FirstName = "Jim", LastName = "Smith" }; Console.WriteLine(customer.LastName); Console.WriteLine(customer.GetPropertyValueAsString("LastName")); customer.SetPropertyValueWithString("LastName", "SmithChanged"); Console.WriteLine(customer.GetPropertyValueAsString("LastName")); Console.ReadLine(); } } class Customer { public int Id { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public int Age { get; set; } public string GetPropertyValueAsString(string propertyName) { PropertyInfo prop = typeof(Customer).GetProperty(propertyName); object value = prop.GetValue(this, null); return value.ToString(); } public void SetPropertyValueWithString(string propertyName, string value) { PropertyInfo prop = typeof(Customer).GetProperty(propertyName); prop.SetValue(this, value, null); } } } post comment |








