- Details
- Written by: Stanko Milosev
- Category: WPF
- Hits: 6904
How to bind command to a button I explained here.
Here is my XAML:
<Window x:Class="UpdateBinding.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:viewModel="clr-namespace:UpdateBinding.ViewModel"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<viewModel:UpdateBindingViewModel x:Key="UpdateBindingBindingViewModel" />
</Window.Resources>
<Grid DataContext="{StaticResource UpdateBindingBindingViewModel}">
<StackPanel>
<TextBox Name="MyTextBox" Text="{Binding Ubm.Name}" VerticalAlignment="Top"/>
<Button VerticalAlignment="Top" Command="{Binding OnButtonClick}">test</Button>
</StackPanel>
</Grid>
</Window>
Command to update value looks like this:
public void UpdateBinding(object obj)
{
Ubm.Name = "Updated value";
OnPropertyChanged(() => this.Ubm);
}
Part of code:
protected void OnPropertyChanged<T>(Expression<Func<T>> property)
{
if (this.PropertyChanged != null)
{
var mex = property.Body as MemberExpression;
string name = mex.Member.Name;
this.PropertyChanged(this, new PropertyChangedEventArgs(name));
}
}
I took from here.
Also don't forget to implement INotifyPropertyChanged interface, in my case declaration of viewmodel looks like this:
public class UpdateBindingViewModel: INotifyPropertyChanged
Example application you can download from here.
---
2014-06-11 Update Just a short notice. If you implement interface by default (with resharper alt + enter :) ) then to use it, you have to write which property of class (view model) are you updating. Something like:
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
if (propertyName == "test")
{
MyHidden = !MyHidden;
myContent = "Clicked!";
}
}
}
Where OnPropertyChanged is called like this:
OnPropertyChanged("MyHidden");
Obviously this example is not compatible with previous example :) I hope I will update this article soon...
---
2014-06-13 Another update
Check out following code:
namespace BooleanToVisibilityConverterExample.ViewModel
{
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Input;
using BooleanToVisibilityConverterExample.Annotations;
public class BooleanToVisibilityConverterExampleViewModel: INotifyPropertyChanged
{
public ICommand OnClick { get; set; }
public bool MyHidden { get; set; }
public BooleanToVisibilityConverterExampleViewModel()
{
OnClick = new RelayCommand(ShowHide);
MyHidden = true;
}
private void ShowHide(object obj)
{
MyHidden = !MyHidden;
OnPropertyChanged("MyHidden");
}
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
var handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
Here notice lines:
MyHidden = !MyHidden;
OnPropertyChanged("MyHidden");
With these lines I said that I want to update property MyHidden which is bounded to rectangle visibility. This update actually is coming from this article, and example you can download from here.
- Details
- Written by: Stanko Milosev
- Category: WPF
- Hits: 5550
I just want to show one more examples of binding.
Beside binding of TreeView to which I already gave an example here, there is another possibility of TreeView binding.
For this example I don't need model, so my view model looks like this:
public class ClassBinding
{
public List<string> MyTest
{
get
{
List<string> pom = new List<string>();
pom.Add("test");
return pom;
}
}
public ClassBinding MyContextTest
{
get
{
return new ClassBinding();
}
}
}
My XAML for tree view binding looks like this:
<Grid>
<TreeView DataContext="{Binding Path=MyContextTest}" ItemsSource="{Binding MyTest}"/>
</Grid>
Notice line {Binding Path=MyContextTest} then notice that MyContextClass is property of the class ClassBinding.
Example project you can download from here.
This article I wrote with help of my colleague from ISE.
- Details
- Written by: Stanko Milosev
- Category: WPF
- Hits: 10861
So, idea was to have to listbox where one list box I will fill with data from MySQL, and in another with data from XML.
This is example is maybe not good, since I don't have model, I just wanted to play with autofac on a simplest possible way.
So here are my interfaces:
public interface IMyTree
{
List<string> Read(List<string> listMyElements);
}
public interface IReadMyTree
{
List<string> ReadXml();
List<string> ReadMySql();
}
Here is the class which will actually return
public class DoMytree : IMyTree
{
public List<string> Read(List<string> listMyElements)
{
return listMyElements;
}
}
Note that this class basically does nothing, that is because I don't have model, so I couldn't pass list of elements, for example, because structure is not same as structure from mySql.
Now, here is example of ReadMySql method:
public class MyReader : IReadMyTree
{
private readonly IMyTree _output;
public MyReader(IMyTree output)
{
this._output = output;
}
public List<string> ReadMySql()
{
string MyConString =
"SERVER=server;" +
"DATABASE=db;" +
"UID=user;" +
"PASSWORD=pass;Convert Zero Datetime=True";
string sql = "select * from slam_categories";
try
{
var connection = new MySqlConnection(MyConString);
var cmdSel = new MySqlCommand(sql, connection);
connection.Open();
MySqlDataReader dataReader = cmdSel.ExecuteReader();
var pom = new List<string>();
while (dataReader.Read())
{
object bugId = dataReader["title"];
pom.Add(bugId.ToString());
}
return _output.Read(pom);
}
catch (Exception e)
{
MessageBox.Show("Error: " + e);
}
return null;
}
}
Note line: return _output.Read(pom); little bit of nonsense I agree :) I just wanted to follow dependency injection... This example is just for learning, remember ;)
Interesting thing to notice are lines:
var connection = new MySqlConnection(MyConString);
var cmdSel = new MySqlCommand(sql, connection);
connection.Open();
MySqlDataReader dataReader = cmdSel.ExecuteReader();
var pom = new List<string>();
while (dataReader.Read())
{
object bugId = dataReader["title"];
pom.Add(bugId.ToString());
}
Here you can see how to fill list of strings from mySql, example how to connect to mySql you find here.
public class ReadMySqlTreeViewAutofacViewModel
{
public static List<string> ReadMySql()
{
var scope = MainWindow.Container.BeginLifetimeScope();
var writer = scope.Resolve<IReadMyTree>();
return writer.ReadMySql();
}
public List<string> TreeMySqlViewModels { get; set; }
public ReadMySqlTreeViewAutofacViewModel()
{
var builder = new ContainerBuilder();
builder.RegisterType<MyReader>().As<IReadMyTree>();
builder.RegisterType<DoMytree>().As<IMyTree>();
MainWindow.Container = builder.Build();
TreeMySqlViewModels = ReadMySql();
}
}
XAML:
<Window x:Class="ReadXmlTreeViewAutofac.View.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:system="clr-namespace:System;assembly=mscorlib"
xmlns:viewModel="clr-namespace:ReadXmlTreeViewAutofac.ViewModel"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<viewModel:TreeViewModel x:Key="TreeViewModel" />
<viewModel:ReadMySqlTreeViewAutofacViewModel x:Key="ReadMySqlTreeViewAutofacViewModel" />
</Window.Resources>
<TabControl>
<TabItem Header="Read from Xml">
<Grid DataContext="{StaticResource TreeViewModel}" OverridesDefaultStyle="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TreeView Grid.Row="0" Grid.Column="0" Name="TvXml" ItemsSource="{Binding Path=TreeXmlViewModels}"/>
</Grid>
</TabItem>
<TabItem Header="Read from MySql">
<Grid OverridesDefaultStyle="True" DataContext="{StaticResource ReadMySqlTreeViewAutofacViewModel}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TreeView Grid.Row="0" Grid.Column="0" Name="TvMySql" ItemsSource="{Binding Path=TreeMySqlViewModels}"/>
</Grid>
</TabItem>
</TabControl>
</Window>
Things to notice in XAML are lines:
xmlns:viewModel="clr-namespace:ReadXmlTreeViewAutofac.ViewModel"
This is namespace which we will use, and lines:
<viewModel:TreeViewModel x:Key="TreeViewModel" />
<viewModel:ReadMySqlTreeViewAutofacViewModel x:Key="ReadMySqlTreeViewAutofacViewModel" />
These are classes which we will use to bind them with our trees, and finally tree binding:
<TreeView Grid.Row="0" Grid.Column="0" Name="TvXml" ItemsSource="{Binding Path=TreeXmlViewModels}"/>
Note that TreeXmlViewModels is property which I am registering it in autofac registration part, also note that I am preparing that property in line TreeXmlViewModels = ReadXml();
Example application you can download from here.
Github is here.
- Details
- Written by: Stanko Milosev
- Category: WPF
- Hits: 8653
One example of creating resizable list boxes:
<Window x:Class="DragNdrop2resize.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>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="2*"/>
</Grid.ColumnDefinitions>
<ListBox Grid.Column="0">
<ListBoxItem Content="List box 1"/>
</ListBox>
<ListBox Grid.Column="1">
<ListBoxItem Content="List box 2"/>
</ListBox>
<GridSplitter Width="5"
HorizontalAlignment="Right"
VerticalAlignment="Stretch"
Background="Red" />
</Grid>
</Window>
As you can see I created column definitions, and added ListBoxes which belong to these columns (Grid.Column="1" for example), and on the end I added GridSpliter. Taken from here.
---
2014-07-26 Update To have vertical resizable list boxes use something like:
<Window x:Class="WpfApplication13.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>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="60"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<ListBox Grid.Row="0">
<ListBoxItem Content="List box 1"/>
</ListBox>
<ListBox Grid.Row="1">
<ListBoxItem Content="List box 2"/>
</ListBox>
<GridSplitter Height="5"
HorizontalAlignment="Stretch"
VerticalAlignment="Bottom"
Background="Red" />
</Grid>
</Window>