Get value in app.config - wpf

I have the Key in app.config:
<appSettings>
<add key="SourceWindow" value="C:\Windows" />
</appSettings>
And in MainWindow.xaml have:
<ObjectDataProvider x:Key="keyFiles" MethodName="GetFiles" ObjectType="{x:Type io:Directory}">
<ObjectDataProvider.MethodParameters>
<sys:String> GET VALUE IN APP.CONFIG </sys:String>
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
How i can get value in app.config -> <add key="SourceWindow" value="C:\Windows" /> and set this value in <sys:String> VALUE </sys:String>
by xaml?
Any suggestion?

To solve your issue, you can write your own MarkupExtension.
I prepared a short sample code for you. First of all let's see the MarkupExtension class that retrive the app.Config's appSettings:
namespace WpfApplication1
{
public class AppSettingsExtension : MarkupExtension
{
private string key;
public AppSettingsExtension()
{
}
public AppSettingsExtension(string key)
{
Key = key;
}
public string Key
{
get
{
return key;
}
set
{
key = value;
}
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
return ConfigurationManager.AppSettings[Key];
}
}
}
Now it is possible to use the AppSettingsExtension in a XAML (not inside a <sys:String /> node, since it already returns a string object):
<Window x:Class="WpfApplication1.MainWindow" Name="win"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication1"
xmlns:io="clr-namespace:System.IO;assembly=mscorlib"
Title="MainWindow" Height="350" Width="400">
<Window.Resources>
<local:AppSettings Key="SourceWindow" x:Key="str" />
<ObjectDataProvider x:Key="keyFiles" MethodName="GetFiles" ObjectType="{x:Type io:Directory}">
<ObjectDataProvider.MethodParameters>
<local:AppSettings Key="SourceWindow" />
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
</Window.Resources>
<StackPanel>
<Label Content="{StaticResource str}" Margin="4" />
<ItemsControl ItemsSource="{Binding Source={StaticResource keyFiles}}" />
</StackPanel>
</Window>
I hope my sample can help you.

Related

Binding DataGridComboBoxColumn to enum value

I'm trying to bind an enum value to DataGridComboBoxColumn, but it does not work. In my case i want to bind the enum CamSegmentType to the DataGridComboBoxColumn. It seems that the enum eCamType could not be found. I don't know what's wrong.
XAML:
<Window x:Class="WpfApp1.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:lvc="clr-namespace:LiveCharts.Wpf;assembly=LiveCharts.Wpf"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
Title="MainWindow" Height="350" Width="825">
<Window.Resources>
<ObjectDataProvider MethodName="GetValues" ObjectType="{x:Type sys:Enum}" x:Key="GetEnumValues">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="local:eCamType"/>
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
</Window.Resources>
<Grid>
<DataGrid Name="dgCamSegements" AutoGenerateColumns="False" Margin="10,180,10,10">
<DataGrid.Columns>
<DataGridComboBoxColumn Header="Value" ItemsSource="{Binding Source={StaticResource GetEnumValues}}" SelectedValueBinding="{Binding CamSegmentType}" />
<DataGridTextColumn Header="Leitwert" Binding="{Binding MasterPosStart}" />
<DataGridTextColumn Header="Folgewert" Binding="{Binding SlavePosStart}" />
</DataGrid.Columns>
</DataGrid>
</Grid>
Code:
namespace WpfApp1
{
public partial class MainWindow : Window
{
public enum eCamType { Gerade, Polynom, };
public class CamSegment
{
public eCamType CamSegmentType { get; set; }
public double MasterPosStart { get; set; }
public double SlavePosStart { get; set; }
}
public MainWindow()
{
InitializeComponent();
...
Can anyone help me?
Add in Your Code:
Mode=TwoWay, UpdateSourceTrigger=PropertyChanged in
SelectedValueBinding DataGridComboBoxColumn

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

Binding to a list of FontWeight and FontStyle values

I am trying to bind to the list of defined FontWeights and FontStyles in WPF.
I was hoping to use the same technique used in this thread about Displaying the list of system fonts; however, I cannot documentation on the get_systemFontFaimlies method for Fonts structure and likewise I cannot find documentation for the FontWeights and FontStyles either.
Thank you for your help.
Edit:
While the response that #ethicallogics provided was helpful, and it is probably more flexible than my solution, I just simply declared arrays in my XAML and chose which FontWeight and FontStyle options I wanted to provide to the end user.
I also found documentation that I couldn't find yesterday for the SystemFonts.get_systemFontFaimlies method here. It is a shame but it appears that the FontWeights and FontStyles structures do not have anything like the get method that the SystemFonts structure has which is why I had to explicitly define arrays with the items that I wanted to provide to the end user.
Here is my XAML for the arrays I defined:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:media="clr-namespace:System.Windows.Media;assembly=PresentationCore"
xmlns:win="clr-namespace:System.Windows;assembly=PresentationCore"
xmlns:sys="clr-namespace:System;assembly=mscorlib">
<ObjectDataProvider x:Key="FontFamilyOptions" ObjectType="{x:Type media:Fonts}" MethodName="get_SystemFontFamilies"/>
<x:Array x:Key="FontWeightOptions" Type="win:FontWeight">
<win:FontWeight>Normal</win:FontWeight>
<win:FontWeight>Bold</win:FontWeight>
<win:FontWeight>ExtraBold</win:FontWeight>
</x:Array>
<x:Array x:Key="FontStyleOptions" Type="win:FontStyle">
<win:FontStyle>Normal</win:FontStyle>
<win:FontStyle>Italic</win:FontStyle>
<win:FontStyle>Oblique</win:FontStyle>
</x:Array>
</ResourceDictionary>
Create a FontWrapper class like
public class FontsWrapper
{
static ICollection<FontWeight> fontWeights;
static ICollection<FontStyle> fontStyles;
static ICollection<FontFamily> fontFamilies;
public static ICollection<FontStyle> GetFontStyles()
{
return fontStyles ?? (fontStyles = new List<FontStyle>() { System.Windows.FontStyles.Italic, System.Windows.FontStyles.Normal, System.Windows.FontStyles.Oblique });//TODO:Get by reflection
}
public static ICollection<FontFamily> GetFontFamilies()
{
return fontFamilies ?? (fontFamilies = Fonts.SystemFontFamilies);
}
public static ICollection<FontWeight> GetFontWeights()
{
if (fontWeights == null)
fontWeights = new List<FontWeight>();
else
return fontWeights;
var type = typeof(FontWeights);
foreach (var p in type.GetProperties().Where(s => s.PropertyType == typeof(FontWeight)))
{
fontWeights.Add((FontWeight)p.GetValue(null, null));
}
return fontWeights;
}
public static ICollection<FontWeight> FontWeights
{
get { return fontWeights ?? (fontWeights = GetFontWeights()); }
}
public static ICollection<FontStyle> FontStyles
{
get { return fontStyles ?? (fontStyles = GetFontStyles()); }
}
public static ICollection<FontFamily> FontFamilies
{
get { return fontFamilies ?? (fontFamilies = GetFontFamilies()); }
}
}
xaml
<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">
<Window.Resources>
<ObjectDataProvider x:Key="fontFamiliesKey" ObjectType="{x:Type local:FontsWrapper}" MethodName="GetFontFamilies"/>
<ObjectDataProvider x:Key="fontWeightsKey" ObjectType="{x:Type local:FontsWrapper}" MethodName="GetFontStyles"/>
<ObjectDataProvider x:Key="fontStylesKey" ObjectType="{x:Type local:FontsWrapper}" MethodName="GetFontWeights"/>
</Window.Resources>
<StackPanel>
<ComboBox ItemsSource="{Binding Source={StaticResource fontFamiliesKey}}"></ComboBox>
<ComboBox ItemsSource="{Binding Source={StaticResource fontWeightsKey}}"></ComboBox>
<ComboBox ItemsSource="{Binding Source={StaticResource fontStylesKey}}"></ComboBox>
<!-- or Bind the Lists of wrapper class Directly -->
<ComboBox ItemsSource="{Binding Source={x:Static local:FontsWrapper.FontFamilies}}"></ComboBox>
<ComboBox ItemsSource="{Binding Source={x:Static local:FontsWrapper.FontStyles}}"></ComboBox>
<ComboBox ItemsSource="{Binding Source={x:Static local:FontsWrapper.FontWeights}}"></ComboBox>
</StackPanel>
I hope this will help.
In the end I just declared arrays as resources (with the options that I wanted to provide to the end user) in my XAML like this:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:media="clr-namespace:System.Windows.Media;assembly=PresentationCore"
xmlns:win="clr-namespace:System.Windows;assembly=PresentationCore"
xmlns:sys="clr-namespace:System;assembly=mscorlib">
<ObjectDataProvider x:Key="FontFamilyOptions" ObjectType="{x:Type media:Fonts}" MethodName="get_SystemFontFamilies"/>
<x:Array x:Key="FontWeightOptions" Type="win:FontWeight">
<win:FontWeight>Normal</win:FontWeight>
<win:FontWeight>Bold</win:FontWeight>
<win:FontWeight>ExtraBold</win:FontWeight>
</x:Array>
<x:Array x:Key="FontStyleOptions" Type="win:FontStyle">
<win:FontStyle>Normal</win:FontStyle>
<win:FontStyle>Italic</win:FontStyle>
<win:FontStyle>Oblique</win:FontStyle>
</x:Array>
</ResourceDictionary>
And I used these as the item sources for my combo boxes like this:
<ComboBox ItemsSource="{Binding Source={StaticResource FontFamilyOptions}}" />
<ComboBox ItemsSource="{Binding Source={StaticResource FontWeightOptions}}" />
<ComboBox ItemsSource="{Binding Source={StaticResource FontStyleOptions}}" />

Bind to result of static class' method

I have the following:
namespace Foo {
public static class Bar {
public static int Fubar() {
return 100;
}
}
}
Now I'm in xaml. I want to use that method to set the height of my rectangle.
<Rectangle Height="{Binding Source=???}">
You need an ObjectDataProvider to bind to a method.
Example (adjust to your NameSpace / Class / Method):
<Window x:Class="SerialPortBinding.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ports="clr-namespace:System.IO.Ports;assembly=System"
Title="MainWindow" SizeToContent="WidthAndHeight">
<Window.Resources>
<ObjectDataProvider ObjectType="{x:Type ports:SerialPort}"
MethodName="GetPortNames" x:Key="portNames"/>
</Window.Resources>
<ComboBox ItemsSource="{Binding Source={StaticResource portNames}}"/>
</Window>
The assembly portion of the xmnls at the top may not be needed; ignore it if it does not come up in CodeSense.
Try something like this:-
{Binding Source={x:Static classnamespace:Bar}, Path=Fubar}

Resource dictionary in User control

I have a user control and it uses resource dictionaries. In that user control, there is another user control which uses same resource dictionaries.what I want to know is whether wpf actually loads it twice and if yes, is there any perfomance impact. Is there any better way to do this.
Thanks in advance.
Interesting question. I was intrigged enough to investigate. It appears that WPF loads a new ResourceDirectionary (and all resources defined and the dictionary which are used) for each appearance of element.
Take a look at the following code:
ViewModel:
public class Person
{
public string name { get; set; }
public int age { get; set; }
public Person() { }
}
Resource (Dictionary1.xaml):
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:so="clr-namespace:SO"
>
<so:Person x:Key="m" name="Methuselah" age="969" />
</ResourceDictionary>
View:
<Window
x:Class="SO.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:so="clr-namespace:SO"
Height="200" Width="300"
Title="SO Sample"
>
<Window.Resources>
<ResourceDictionary Source="Dictionary1.xaml" />
</Window.Resources>
<StackPanel DataContext={StaticResource m}>
<UserControl>
<UserControl.Resources>
<ResourceDictionary Source="Dictionary1.xaml" />
</UserControl.Resources>
<TextBlock x:Name="inner" DataContext="{StaticResource m}" Text="{Binding Path=name}" />
</UserControl>
<TextBlock x:Name="outer" Text="{Binding Path=name}" />
<Button Click="Button_Click">Change</Button>
</StackPanel>
</Window>
Put a breakpoint at the Person() constructor and notice the object is instantiated twice. Or, make Person implementing INotifyPropertyChange, and add the following code for Button_Click:
private void Button_Click( object sender, RoutedEventArgs e ) {
Person innerPerson = this.inner.DataContext as Person;
Person outerPerson = this.outer.DataContext as Person;
innerPerson.name = "inner person";
outerPerson.name = "outer person";
}
If you want to have a single instance of each resource, have the reousrces in the element of app.xaml file.

Resources