I have a strange problem with the WebView component in WinRT. I use it to display either a Website via Soure property binding or local content with NavigateToString.
My problem is the following:
If I change the Source property, it naviagtes to the Website. Then, I call NavigateToString and it displays the content correctly. After that I change the Source property again, but navigation doesn't start and the local content remains present.
Also if I first call NavigateToString and then change Source property, no navigation starts.
I prepared a small sample project to illustrate my problem: http://1drv.ms/1HI8p3I
EDIT:
I updated the sample project above. I tried to call Naviagte via an Attached Property instead of changing the Source property but I got the same issue. Once I call NavigateToString, all other updates of bindings don't work.
This is my class with the Attached properties for WebView:
public class WebViewEx
{
#region ContentString
public static readonly DependencyProperty ContentStringProperty =
DependencyProperty.RegisterAttached("ContentString", typeof(string), typeof(WebViewEx), new PropertyMetadata("", new PropertyChangedCallback(OnContentStringPropertyChanged)));
public static void SetContentString(DependencyObject obj, string contentString)
{
obj.SetValue(ContentStringProperty, contentString);
}
public static string GetContentString(DependencyObject obj)
{
return (string)obj.GetValue(ContentStringProperty);
}
private static void OnContentStringPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
WebView webView = d as WebView;
if (webView != null)
{
webView.NavigateToString((string)e.NewValue);
}
}
#endregion
#region UriString
public static readonly DependencyProperty UriStringProperty =
DependencyProperty.RegisterAttached("UriString", typeof(string), typeof(WebViewEx), new PropertyMetadata("", new PropertyChangedCallback(OnUriStringPropertyChanged)));
public static void SetUriString(DependencyObject obj, string uriString)
{
obj.SetValue(UriStringProperty, uriString);
}
public static string GetUriString(DependencyObject obj)
{
return (string)obj.GetValue(UriStringProperty);
}
private static void OnUriStringPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
WebView webView = d as WebView;
if (webView != null)
{
webView.Navigate(new Uri((string)e.NewValue));
}
}
#endregion
}
Related
Hello I have issue with binding to user control animation, after I bind data to user control(which is bool type) it sets correct values to user control data, but does not trigger animation, I tried to use PropertyChangedCallback but with no luck user control code below:
private static Switch_box AppWindow;
public Switch_box()
{
InitializeComponent();
AppWindow = this;
}
public static readonly DependencyProperty CheckboxStatusProperty = DependencyProperty.Register(nameof(CheckboxStatus), typeof(bool), typeof(Switch_box), new PropertyMetadata(false, new PropertyChangedCallback(OnCurrentReadingChanged)));//cant remove static otherwise throws error
public bool CheckboxStatus
{
get
{
return (bool)GetValue(CheckboxStatusProperty);
}
set
{
/* if (value == true)
{
((Storyboard)FindResource("OnChecking")).Begin(this);
}
else
{
((Storyboard)FindResource("OnUnchecking")).Begin(this);
}*/
SetValue(CheckboxStatusProperty, value);
}
}
private static void OnCurrentReadingChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)//cant remove static due to PropertyChangedCallBack requires static otherwise it throws error
{
AppWindow.OnChecking((bool)d.GetValue(CheckboxStatusProperty));
}
private void OnChecking(bool Status)
{
switch (Status)
{
case true:
{
((Storyboard)FindResource("OnChecking")).Begin(this);
break;
}
case false:
{
((Storyboard)FindResource("OnUnchecking")).Begin(this);
break;
}
}
}
And my usercontrol bind line:
<local:Switch_box Tag="{Binding Index,IsAsync=True}" Checked="Switch_box_Checked" Unchecked="Switch_box_Unchecked" CheckboxStatus="{Binding IsEnabled,IsAsync=True}"/>
How to trigger animation after CheckboxStatus variable is changed?
EDIT 1: updated code.
There is a naming convention. _StatusBox should be named CheckboxStatusProperty, and it should be public:
public static readonly DependencyProperty CheckboxStatusProperty =
DependencyProperty.Register(
nameof(CheckboxStatus), typeof(bool), typeof(Switch_box),
new PropertyMetadata(false, OnCurrentReadingChanged));
You must not call anything else than GetValueand SetValue in the CLR wrapper of a dependency property. And you call the methods on the current instance, not on a static field:
public bool CheckboxStatus
{
get { return (bool)GetValue(CheckboxStatusProperty); }
set { SetValue(CheckboxStatusProperty , value); }
}
In the PropertyChangedCallback it is pointless to set the property another time. And again, you should operate on the current DependencyObject instance, i.e. d, not on a static field:
private static void OnCurrentReadingChanged(
DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((Switch_box)d).OnChecking((bool)e.NewValue);
}
private void OnChecking(bool status)
{
if (status)
{
((Storyboard)FindResource("OnChecking")).Begin(this);
}
else
{
((Storyboard)FindResource("OnUnchecking")).Begin(this);
}
}
I have two dependency properties and when value in First changes, I would like to update also the Second - for example give it temporary value and update UI, but I don't want to break the binding on Second property.
public bool Frist
{
get { return (bool)GetValue(FristProperty); }
set { SetValue(FristProperty, value); }
}
public static readonly DependencyProperty FristProperty =
DependencyProperty.Register("Frist", typeof(bool), typeof(ItemControl), new PropertyMetadata(false, FirstUpdated));
private static void FirstUpdated(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var theControl = d as ItemsControl;
// I would like to update also second dependency property here
// for example if First == true, then Second = Overriden
// else Second = the value from binding
}
public string Second
{
get { return (string)GetValue(SecondProperty); }
set { SetValue(SecondProperty, value); }
}
public static readonly DependencyProperty SecondProperty =
DependencyProperty.Register("Second", typeof(string), typeof(ItemsControl), new PropertyMetadata(string.Empty));
I've taken a look at various samples from WPF, but seems like there are missing things in UWP. What are the options?
I am developing a Windows phone app, and I have this logic:
I have a chat view, with ListView which contain video or text messages. My video messages are custom controls which implements my IPlayableMessage interface:
public class VideoMessage : Grid , IPlayableMessage
{
public VideoMessage()
{
this.Loaded += Loaded;
}
private void Loaded(object sender, RoutedEventArgs e)
{
MessagePlayer.Sub(this);
}
public void Play()
{
//Some logic for video play
}
public Player MessagePlayer
{
get { return (Player)GetValue(MessagePlayerProperty); }
set { SetValue(MessagePlayerProperty, value); }
}
public static readonly DependencyProperty MessagePlayerProperty =
DependencyProperty.Register("MessagePlayer", typeof(Player), typeof(VideoMessage), null);
}
This is my interface:
public interface IPlayableMessage
{
void Play(Uri uri = null);
}
In the constructor I am calling Sub method with this parameter, which enabls my in the future to play my video message.
This works great, however if I add a new message to my ListView (and I see it on the view) the controls constructor isn't called and by that my object is not passing it self to the Player.
Why the constructor and Loaded events are not called when new element added to the ListView?
The constructor called thought, as I scroll up and down the ListView and it performs its paging....
After a while I've moved my registration to:
protected override Size ArrangeOverride(Size finalSize)
It reduced the numbers of unregistered grids but it's called several times per object and it's also does not cover a 100 percent of the items.
Any help will be appreciated. :)
Did you try to add callback to the MessagePlayer property and handle operation there?
public static readonly DependencyProperty MessagePlayerProperty = DependencyProperty.Register(
"MessagePlayer", typeof (Player), typeof (VideoMessage), new PropertyMetadata(default(Player), PropertyChangedCallback));
private static void PropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var control = d as VideoMessage;
(e.NewValue as Player).Sub(control);
}
I am using the WPF WebBrowser control to display a PDF. I want to disable the context menu.
I have already tried the following -
Disable context menu in Internet Explorer control -
In the constructor, added the following -
webBrowser.LoadCompleted +=new LoadCompletedEventHandler(webBrowser_LoadCompleted);
// Event Handler
public void webBrowser_LoadCompleted(object sender, NavigationEventArgs e )
{
webBrowser.ContextMenu = null;
var t = webBrowser.Document as System.Windows.Forms.HtmlDocument;
// t is always coming as null, even though I can clearly see the pdf in the web browser control.
if(t != null)
{
t.ContextMenuShowing += new System.Windows.Forms.HtmlElementEventHandler(t_ContextMenuShowing);
}
}
Also checked http://social.msdn.microsoft.com/forums/en-US/wpf/thread/7c283faf-16c8-4b4e-a362-f292e3032abb/.
Used the approach to set the registry - HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Internet Explorer\Restrictions\NoBrowserContextMenu to DWORD 1.
When I set the regisrty, the PDF does not get displayed properly.
Also, since I am using PDF to display, I cannot set - in body -
oncontextmenu="return false;"
Cannot set IsWebBrowserContextMenuEnabled as I am using WPF web browser control.
It could be because of the PDF visualizer that wants to show it's own context menu.
Which context menu are you seeing? The one of IE or the one of the PDF visualizer?
I would also try to use the System.Windows.Forms.WebBrowser (you can use it in WPF). I used it in a WPF application because it has more functionality than the one of WPF.
You can wrap the Windows Forms WebBrowser to be bindable and disable the context menu (and access to other properties) in an easy way:
public class WindowsFormsWebBrowser : WindowsFormsHost
{
public static readonly DependencyProperty HtmlProperty =
DependencyProperty.Register(
"Html",
typeof(string),
typeof(WindowsFormsWebBrowser),
new PropertyMetadata(string.Empty, OnHtmlChanged, null));
public static readonly DependencyProperty IsContentMenuEnabledProperty =
DependencyProperty.Register(
"IsContentMenuEnabled",
typeof(bool),
typeof(WindowsFormsWebBrowser),
new PropertyMetadata(true, OnIsContextMenuEnabledChanged));
private readonly System.Windows.Forms.WebBrowser webBrowser = new System.Windows.Forms.WebBrowser();
public WindowsFormsWebBrowser()
{
Child = webBrowser;
}
public string Html
{
get { return GetValue(HtmlProperty) as string; }
set { SetValue(HtmlProperty, value); }
}
public bool IsContentMenuEnabled
{
get { return (bool)GetValue(IsContentMenuEnabledProperty); }
set { SetValue(IsContentMenuEnabledProperty, value); }
}
private static void OnHtmlChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var browser = d as WindowsFormsWebBrowser;
if (browser == null)
{
return;
}
browser.webBrowser.DocumentText = (string)e.NewValue;
}
private static void OnIsContextMenuEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var browser = d as WindowsFormsWebBrowser;
if (browser == null)
{
return;
}
browser.webBrowser.IsWebBrowserContextMenuEnabled = (bool)e.NewValue;
}
}
Here the steps to reference Windows Forms controls in a WPF project.
Here is a solution:
private void WebBrowser_LoadCompleted(object sender, System.Windows.Navigation.NavigationEventArgs e)
{
((WebBrowser)sender).InvokeScript("eval",
"$(document).contextmenu(function() { return false; });");
}
Just use
// Disable the Context menu inside the web browser
webBrowser1.IsWebBrowserContextMenuEnabled = false;
i tried this in Windows Applications
I have a WPF Application using MVVM pattern. I have a Window in my project and use a CustomControl in my Window.
I need two commands in my Window for Start and Stop in my CustomControl . So I use a bool DependencyProperty like this :
public static readonly DependencyProperty IsStartModeProperty = DependencyProperty.Register(
"IsStartMode", typeof(bool), typeof(RadarView), new FrameworkPropertyMetadata(false, OnCurrentReadingChanged));
public bool IsStartMode {
get { return (bool)GetValue(IsStartModeProperty); }
set { SetValue(IsStartModeProperty, value); }
}
Also following method is use for callback delegate in my dependency property:
public static void OnCurrentReadingChanged(DependencyObject doj, DependencyPropertyChangedEventArgs dp) {
if (IsStartMode)
Start();
else
Stop();
}
My problem is in use from IsStartMode property in up method, because this is not static. It has a build error.
Is Correct my solution? if is correct what I do?
You need to cast the first method argument to your Dependency Object class:
public static void OnCurrentReadingChanged(DependencyObject doj, DependencyPropertyChangedEventArgs dp)
{
var myObject = (RadarView)doj;
if (myObject.IsStartMode)
myObject.Start();
else
myObject.Stop();
}
(As a side note, I would call the property IsRunning.)