Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Made an MVVM friendly example. #30

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions CefSharp.MinimalExample.Wpf/Binding/Behaviors/HtmlBindingHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using CefSharp.Wpf;
using System.Windows;

namespace CefSharp.MinimalExample.Wpf.Binding.Behaviors
{
public static class HtmlBindingHelper
{
// Using a DependencyProperty as the backing store for Html. This enables animation, styling, binding, etc...
public static readonly DependencyProperty HtmlProperty =
DependencyProperty.RegisterAttached(
"Html",
typeof(string),
typeof(HtmlBindingHelper),
new PropertyMetadata(string.Empty, OnHtmlChanged));

public static string GetHtml(DependencyObject obj)
{
return (string)obj.GetValue(HtmlProperty);
}

public static void SetHtml(DependencyObject obj, string value)
{
obj.SetValue(HtmlProperty, value);
}

private static void OnHtmlChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
string htmlText = e.NewValue as string;

if (string.IsNullOrWhiteSpace(htmlText))
{
htmlText = string.Empty;
}

((ChromiumWebBrowser)d).LoadHtml(htmlText, "http://cefsharp/loadHtml");
}
}
}
24 changes: 24 additions & 0 deletions CefSharp.MinimalExample.Wpf/Binding/BindableBase.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using System.ComponentModel;
using System.Runtime.CompilerServices;

namespace CefSharp.MinimalExample.Wpf.Binding
{
public class BindableBase : INotifyPropertyChanged
{
protected virtual void SetProperty<T>(ref T member, T val,
[CallerMemberName] string propertyName = null)
{
if (object.Equals(member, val)) { return; }

member = val;
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}

protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}

public event PropertyChangedEventHandler PropertyChanged = delegate { };
}
}
98 changes: 98 additions & 0 deletions CefSharp.MinimalExample.Wpf/Binding/RelayCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
using System;
using System.Windows.Input;

namespace CefSharp.MinimalExample.Wpf.Binding
{
public class RelayCommand : ICommand
{
Action _TargetExecuteMethod;
Func<bool> _TargetCanExecuteMethod;

public RelayCommand(Action executeMethod)
{
_TargetExecuteMethod = executeMethod;
}

public RelayCommand(Action executeMethod, Func<bool> canExecuteMethod)
{
_TargetExecuteMethod = executeMethod;
_TargetCanExecuteMethod = canExecuteMethod;
}

public void RaiseCanExecuteChanged()
{
CanExecuteChanged(this, EventArgs.Empty);
}
#region ICommand Members

bool ICommand.CanExecute(object parameter)
{
if (_TargetCanExecuteMethod != null)
{
return _TargetCanExecuteMethod();
}
if (_TargetExecuteMethod != null)
{
return true;
}
return false;
}

// Beware - should use weak references if command instance lifetime is longer than lifetime of UI objects that get hooked up to command
// Prism commands solve this in their implementation
public event EventHandler CanExecuteChanged = delegate { };

void ICommand.Execute(object parameter)
{
_TargetExecuteMethod?.Invoke();
}
#endregion
}

public class RelayCommand<T> : ICommand
{
Action<T> _TargetExecuteMethod;
Func<T, bool> _TargetCanExecuteMethod;

public RelayCommand(Action<T> executeMethod)
{
_TargetExecuteMethod = executeMethod;
}

public RelayCommand(Action<T> executeMethod, Func<T, bool> canExecuteMethod)
{
_TargetExecuteMethod = executeMethod;
_TargetCanExecuteMethod = canExecuteMethod;
}

public void RaiseCanExecuteChanged()
{
CanExecuteChanged(this, EventArgs.Empty);
}
#region ICommand Members

bool ICommand.CanExecute(object parameter)
{
if (_TargetCanExecuteMethod != null)
{
T tparm = (T)parameter;
return _TargetCanExecuteMethod(tparm);
}
if (_TargetExecuteMethod != null)
{
return true;
}
return false;
}

// Beware - should use weak references if command instance lifetime is longer than lifetime of UI objects that get hooked up to command
// Prism commands solve this in their implementation
public event EventHandler CanExecuteChanged = delegate { };

void ICommand.Execute(object parameter)
{
_TargetExecuteMethod?.Invoke((T)parameter);
}
#endregion
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</ApplicationDefinition>
<Compile Include="Binding\Behaviors\HtmlBindingHelper.cs" />
<Compile Include="Binding\RelayCommand.cs" />
<Page Include="MainWindow.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
Expand All @@ -94,7 +96,9 @@
<DependentUpon>App.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="Binding\BindableBase.cs" />
<Compile Include="Binding\TitleConverter.cs" />
<Compile Include="MainViewModel.cs" />
<Compile Include="MainWindow.xaml.cs">
<DependentUpon>MainWindow.xaml</DependentUpon>
<SubType>Code</SubType>
Expand Down
37 changes: 37 additions & 0 deletions CefSharp.MinimalExample.Wpf/MainViewModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using CefSharp.MinimalExample.Wpf.Binding;
using System.Windows.Input;

namespace CefSharp.MinimalExample.Wpf
{
public class MainViewModel : BindableBase
{
private string html;

public MainViewModel()
{
ViewHtmlCommand = new RelayCommand(OnViewHtml);
Address = "www.google.com";
}

public string Html
{
get { return html; }
set { SetProperty(ref html, value); }
}

private string address;

public string Address
{
get { return address; }
set { SetProperty(ref address, value); }
}

public ICommand ViewHtmlCommand { get; private set; }

private void OnViewHtml()
{
Html = "<div dir=\"ltr\"><b><i>test</i></b></div>\r\n";
}
}
}
48 changes: 39 additions & 9 deletions CefSharp.MinimalExample.Wpf/MainWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:wpf="clr-namespace:CefSharp.Wpf;assembly=CefSharp.Wpf"
xmlns:behaviors="clr-namespace:CefSharp.MinimalExample.Wpf.Binding.Behaviors"
Title="{Binding Path=Title, ElementName=Browser, Converter={StaticResource TitleConverter}}"
WindowState="Maximized">
<Grid>
Expand All @@ -11,16 +12,45 @@
</Grid.RowDefinitions>
<wpf:ChromiumWebBrowser Grid.Row="0"
x:Name="Browser"
Address="http://www.google.com" />
Address="{Binding Address}"
behaviors:HtmlBindingHelper.Html="{Binding Html}"/>

<StatusBar Grid.Row="1">
<ProgressBar HorizontalAlignment="Right"
IsIndeterminate="{Binding IsLoading, ElementName=Browser}"
Width="100"
Height="16"
Margin="3" />
<Separator />
<!-- TODO: Could show hover link URL here -->
<TextBlock Text="{Binding Address, ElementName=Browser}"/>
<StatusBar.ItemsPanel>
<ItemsPanelTemplate>
<Grid >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
</Grid>
</ItemsPanelTemplate>
</StatusBar.ItemsPanel>
<StatusBarItem>
<Button Content="View HTML" Command="{Binding ViewHtmlCommand}" Padding="3,0"/>
</StatusBarItem>
<Separator Grid.Column="1"/>
<StatusBarItem Grid.Column="2">
<ProgressBar HorizontalAlignment="Right"
IsIndeterminate="{Binding IsLoading, ElementName=Browser}"
Width="100"
Height="16"
Margin="3" />
</StatusBarItem>
<Separator Grid.Column="3"/>
<StatusBarItem Grid.Column="4">
<!-- TODO: Could show hover link URL here -->
<TextBlock Text="{Binding Address, ElementName=Browser}" />
</StatusBarItem>
<Separator Grid.Column="5"/>
<StatusBarItem Grid.Column="6" HorizontalContentAlignment="Stretch">
<TextBox Text="{Binding Address, UpdateSourceTrigger=PropertyChanged}" />
</StatusBarItem>
</StatusBar>
</Grid>
</Window>
1 change: 1 addition & 0 deletions CefSharp.MinimalExample.Wpf/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ public partial class MainWindow : Window
public MainWindow()
{
InitializeComponent();
DataContext = new MainViewModel();
}
}
}