Skip to content

Instantly share code, notes, and snippets.

@battermann

battermann/App.xaml.cs

Last active Dec 8, 2018
Embed
What would you like to do?
Typesafe conversion of viewmodel property to observable stream
using System.Windows;
namespace PropertyToobsevable
{
public partial class App : Application
{
private void Application_Startup(object sender, StartupEventArgs e)
{
var vm = new MainWindowViewModel();
var mainWindow = new MainWindow { DataContext = vm };
mainWindow.Show();
}
}
}
<Window x:Class="PropertyToobsevable.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">
<StackPanel Margin="10">
<DockPanel>
<Label DockPanel.Dock="Left" Content="Input:" />
<TextBox x:Name="InputTextBox" Focusable="True" Text="{Binding Input, UpdateSourceTrigger=PropertyChanged}"/>
</DockPanel>
<ListBox ItemsSource="{Binding Output}" Margin="0,10,0,0" Height="250"/>
</StackPanel>
</Window>
using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Linq.Expressions;
using System.Reactive.Linq;
using System.Reflection;
namespace PropertyToObsevable
{
public class MainWindowViewModel : INotifyPropertyChanged
{
private string _input;
private ObservableCollection<string> _output = new ObservableCollection<string>();
public ObservableCollection<string> Output
{
get { return _output; }
set
{
if (Equals(Output, value))
return;
_output = value;
OnPropertyChanged("Output");
}
}
public string Input
{
get { return _input; }
set
{
if (Equals(Input, value))
return;
_input = value;
OnPropertyChanged("Input");
}
}
public MainWindowViewModel()
{
this.ToObservable(() => Input)
.Subscribe(Output.Add);
}
private void OnPropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
}
using System;
using System.ComponentModel;
using System.Linq;
using System.Linq.Expressions;
using System.Reactive.Linq;
using System.Reflection;
namespace PropertyToobsevable
{
public static class NotifyPropertyChangedExtensions
{
var memberExpression = propertyExpression.Body as MemberExpression;
return memberExpression == null
? Observable.Empty<T>()
: Observable
.FromEventPattern<PropertyChangedEventArgs>(source, "PropertyChanged")
.Where(e => e.EventArgs.PropertyName == memberExpression.Member.Name)
.SelectMany(_ => source.GetType()
.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
.Where(info => info.Name == memberExpression.Member.Name))
.Select(info => (T)info.GetValue(source));
}
}
}
@jakehockey10

This comment has been minimized.

Copy link

@jakehockey10 jakehockey10 commented Dec 8, 2018

Was this ever compiled? NotifyPropertyChangedExtensions is not a valid class.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment