|
I am not a pro so this may not work. Set the ComboBox Datasource to the JobListView.(Or the View Model)
Hope this helps.
Edit Changed the subject title so others might help.
Frazzle the name say's it all
Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live.
John F. Woods
|
|
|
|
|
There is no data to bind to. The data for the control is retreived from inside the control, not bound to the combo.
I'm trying to use the combobox to simple pop open the user conrrol
If it's not broken, fix it until it is
|
|
|
|
|
Then it seems that the Usercontrol should have contained a TextBox A Button with a drop down arrow and the ListView with visability set to collapsed. Then on the Button click open the ListView.
Frazzle the name say's it all
Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live.
John F. Woods
|
|
|
|
|
Why would it show anything? Think about what your XAML is doing. You set the ComboBox.ItemTemplate to show a views:JobListView. You just said "I want to render each item (in both the edit box and the drop down list) as a views:JobListView". So, if you have 10 items, you are going to get 10 views:JobListView plus another one in the edit box. Probably not what you meant .
As I have mentioned to you in the past, you really need to aquire a tool that will allow you to dump out control templates, so you understand how they are put together so you can do these types of mods as you get more advanced.
I would highly recommend you install Expression Blend Preview since its now free and allows you to dump out control templates easily as well as modify them visually.
Also, in your response to the other guy, you said you didn't set the combo box ItemsSource to anything and wanted the JobListView to retrieve everything. That won't work on a conceptual level. How is the edit box in the combo box going to display the selected item when it knows nothing about the collection?
You need to have the VM that owns the combo box own the collection and set the combo box ItemsSource to it. The edit box will show the selected item and the popup view will render as your JobListView.
I'm not going to post the ComboBox control template here since its quite large (200+ lines of XAML), but I did dump it out for discussion purposes.
There isn't an easy way to style the drop down list because its essentially an ItemsPresenter and doesn't have any built in templates for that.
You *might* be able to wait for the combo box template to be applied and then find the "DropDownScrollViewer" control by name and replace its content with your control. I haven't tried this, so its possible it won't work. If I was doing this task, I'd probably try it first though. Otherwise, it looks like you are going to have to dump out the control template and replace the ItemsPresenter with your joblistview.
|
|
|
|
|
Hey all!
Does anyone know of a good, functional Windows 8 theme for WPF? I'd like something like GitHub's desktop GUI theme.
Thanks!
|
|
|
|
|
You could use MahApps; http://mahapps.com/MahApps.Metro/[^]
"As beings of finite lifespan, our contributions to the sum of human knowledge is one of the greatest endeavors we can undertake and one of the defining characteristics of humanity itself"
|
|
|
|
|
|
I am trying to provide a UserControl that wrappers up the WebBrowser control and provides the additional events raised on the DWebBrowserEvents_Event and DWebBrowserEvents2_Event interfaces.
I have a class that works fine when only one extended browser control is in the xaml hwever when I have 2 the second one works but the first is failing to show the page its pointed at.
The user control code is as follows
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;
namespace CustomControls
{
public partial class ExtWebBrowser : UserControl
{
private static WebBrowser baseBrowser;
private SHDocVw.DWebBrowserEvents_Event wbEvents;
private SHDocVw.DWebBrowserEvents2_Event wbEvents2;
private SHDocVw.IWebBrowser2 myWebBrowser2;
static ExtWebBrowser()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(ExtWebBrowser), new FrameworkPropertyMetadata(typeof(ExtWebBrowser)));
}
public ExtWebBrowser()
{
}
#region Dependency Properties
#region UrlProperty
public Uri Url
{
get {
return (Uri)GetValue(UrlProperty);
}
set {
SetValue(UrlProperty, value);
}
}
public static readonly DependencyProperty UrlProperty =
DependencyProperty.Register("Url", typeof(Uri), typeof(ExtWebBrowser), new UIPropertyMetadata(new Uri("about:blank"), UrlChanged));
private static void UrlChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
if (baseBrowser != null)
{
baseBrowser.Source = e.NewValue as Uri;
}
}
#endregion
#region ScriptingObjectProperty
public object ScriptingObject
{
get {
return (object)GetValue(ScriptingObjectProperty); }
set {
SetValue(ScriptingObjectProperty, value); }
}
public static readonly DependencyProperty ScriptingObjectProperty =
DependencyProperty.Register("ScriptingObject", typeof(object), typeof(ExtWebBrowser), new UIPropertyMetadata(null, ScriptingObjectChanged));
private static void ScriptingObjectChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
if (baseBrowser != null)
{
baseBrowser.ObjectForScripting = e.NewValue;
}
}
#endregion ScriptingObjectProperty
#endregion Dependecy Properties
#region Member fields
private bool _firstLoad = false;
#endregion
#region Internals
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
baseBrowser = base.Template.FindName("PART_baseBrowser", this) as WebBrowser;
if (baseBrowser != null)
{
_firstLoad = true;
baseBrowser.LoadCompleted += new LoadCompletedEventHandler(baseBrowser_LoadCompleted);
baseBrowser.ObjectForScripting = ScriptingObject;
baseBrowser.Source = new Uri("about:blank");
}
}
void baseBrowser_LoadCompleted(object sender, NavigationEventArgs e)
{
if (_firstLoad)
{
Guid SID_SWebBrowserApp = new Guid("0002DF05-0000-0000-C000-000000000046");
IServiceProvider serviceProvider = (IServiceProvider)baseBrowser.Document;
Guid serviceGuid = SID_SWebBrowserApp;
Guid iid = typeof(SHDocVw.IWebBrowser2).GUID;
myWebBrowser2 = (SHDocVw.IWebBrowser2)serviceProvider.QueryService(ref serviceGuid, ref iid);
wbEvents = (SHDocVw.DWebBrowserEvents_Event)myWebBrowser2;
wbEvents2 = (SHDocVw.DWebBrowserEvents2_Event)myWebBrowser2;
baseBrowser.Source = Url;
_firstLoad = false;
}
}
#endregion Internals
}
[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("6d5140c1-7436-11ce-8034-00aa006009fa")]
internal interface IServiceProvider
{
[return: MarshalAs(UnmanagedType.IUnknown)]
object QueryService(ref Guid guidService, ref Guid riid);
}
}
The xaml is as follows
<Window x:Class="UCA.ChordiantWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:custom="clr-namespace:CustomControls;assembly=Uca.CustomControls"
Title="ChordiantWindow" Height="300" Width="300" SizeToContent="WidthAndHeight" ResizeMode="NoResize">
<Window.Resources>
<Style TargetType="{x:Type custom:ExtWebBrowser}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type custom:ExtWebBrowser}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<Grid>
<Button>Hello</Button>
<WebBrowser x:Name="PART_baseBrowser" />
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<StackPanel>
<custom:ExtWebBrowser Url="http://www.amazon.co.uk" />
<custom:ExtWebBrowser Url="http://www.microsoft.com" />
</StackPanel>
</Grid>
</Window>
What have I got wrong?
EDIT
Thought it might be the dreaded WebBrowser control itself however the page works if I use to Webrowser contols rather than the extended one.
Also It looks like the Url DP gets shared as another page with the control in seems to change its content in-line with changes to the window?
Ian Cox
----------------------------------------------------------
The more simple it looks, the harder it is to do!
modified 28-Mar-13 14:22pm.
|
|
|
|
|
Coxianuk wrote: private static WebBrowser baseBrowser;
There's your problem - your control is only ever using a single instance of the WebBrowser control, no matter how many instances of your control you create.
It looks like the only reason you've made it static is so that you can access it from the DependencyPropertyChanged events. All you need to do is cast the DependencyObject parameter to your ExtWebBrowser class, and you'll be able to access non-static fields, properties, and methods.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
modified 28-Mar-13 17:01pm.
|
|
|
|
|
Thanks for that Think I got a little code blind!
Changed the
private static WebBrowser baseBrowser;
to
internal WebBrowser baseBrowser;
and the Onchanged events to
private static void UrlChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
ExtWebBrowser ext = o as ExtWebBrowser;
if (ext != null)
{
ext.baseBrowser.Source = e.NewValue as Uri;
}
}
private static void ScriptingObjectChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
ExtWebBrowser ext = o as ExtWebBrowser;
if (ext != null)
{
ext.baseBrowser.ObjectForScripting = e.NewValue;
}
}
It all works fine.
Thanks again
Ian
modified 29-Mar-13 4:22am.
|
|
|
|
|
Thank You! I just learned something new.
Frazzle the name say's it all
Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live.
John F. Woods
|
|
|
|
|
Hi there i have recently decided that i wanted to start playing around with app development. I was woundering if anyone can point me to any good information sources for such task. I dont know any xaml or silverlight so im learning from the ground up. Any books you can recommened, web sites, anything really.
|
|
|
|
|
|
|
Hi,
I don't know if this is the place to ask,
I'm looking for a windows phone 7.1 XNA programmer for writing a game.
If anyone is interested, please contact me.
|
|
|
|
|
|
|
I want a StackPanel to be populated by one button for each entry in an ArrayList. I can set up these buttons from the ArrayList using a foreach sequence. But how would I define the corresponding event handlers?
Scratching his newbie head
---Dirk Bock
|
|
|
|
|
Each button calls the same event (Command) and passes in the commandparameter which should be bound to the object in the collection. So the method receives and object that can then be cast as the item in the collection.
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
Button btn = new Button();
btn.Click += new RoutedEventHandler( button_Click );
...
void button_Click( object sender, RoutedEventArgs e ) {
Button btn = sender as Button;
...
}
|
|
|
|
|
I'm struggling to get my MVVM WPF app to work with a set of Tasks updating the UI.
I've got a Command that starts X number of tasks off, for each task I'd like the UI to update when started and when finished. I've also got a second Command to cancel the task, which I'd obviously like working (the code does but as the UI locks the button doesn't)
I've used a ListBox bound to an ObvservableCollection<string> for the results, as this seemed better than binding to a string .
At the moment I get the UI lockup until all tasks are finished. This is with or without a Task.WaitAll . The results are correct, the tasks don't always start/finish in the same order so they're obviously being generated and updating the collection asynchronously.
I've tried an AysncObservableCollection (as per this SO answer)
I've tried using the Dispatcher in my method that adds a item to the collection.
I've tried variations on the Binding parameters.
Can someone give me some hints Surely people have created a status log with async stuff in MVVM before??
Do I need to move the task creation to the Model?
I've seen mention of making sure the Collection is initiated on/by the View, not sure I understand that!
The View has a DataContext that's set to my ViewModel. Do they mean I've got to create the Collection in the code behind of the View? that doesn't seem right.
Oh this is .NET4.0 on XP, and I'm not using any MVVM frameworks (didn't think that was a good idea as I'm still learning)
|
|
|
|
|
How are you binding the ListBox and ObservableCollection<string> ?
Are you creating the ObservableCollection in the ViewModel?
Is it bound to the ItemsSource on the ListBox ?
If you can show some of the code/xaml we can provide more assistance.
|
|
|
|
|
Ok,
In my view XAML I think the only relevant bits are:
<UserControl.DataContext>
<local:ViewModelLoadTest />
</UserControl.DataContext>
<Button Height="32"
Width="128"
Margin="5"
Content="Run Test"
Command="{Binding RunTestCommand}"/>
<ListBox ScrollViewer.VerticalScrollBarVisibility="Visible"
FontFamily="Consolas"
FontSize="12"
ItemsSource="{Binding Path=Results}">
</ListBox>
I've tried some of the Binding options like Async.
There's nothing in the .xaml.cs file apart from the initialize call. Oh and its in a UserControl because my app has two modes so I'm using a tab control displaying two UserControls.
For my ViewModel, I've got an abstract base ViewModel then a design time and run time classes.
All the child classes do is set some properties, there's no other methods or additional properties.
In the base ViewModel class the collection is defined:
private ObservableCollection<string> _results = new ObservableCollection<string>();
public ObservableCollection<string> Results
{
get { return _results; }
set
{
_results = value;
RaisePropertyChanged("Results");
}
}
I've tried the creation of the collection in the constructor of the BaseViewModel and in the constructors of the child classes.
And in case its my Task stuff that's wrong:
private void DoRunTestCommand()
{
_cancellationTokenSource = new CancellationTokenSource();
Log(String.Format("Submitting {0} requests, every {1}ms, {2} at time."
, Model.NumberOfRequests
, Model.MSBetweenRequests
, Model.NumberOfConcurrentRequests));
CancellationToken cancellationToken = _cancellationTokenSource.Token;
Task[] tasks = new Task[Model.NumberOfRequests];
for (int i = 0; i < Model.NumberOfRequests; i++)
{
int idx = i;
Task r = Task.Factory.StartNew((state) =>
{
SubmitRequest((int) state);
cancellationToken.ThrowIfCancellationRequested();
}
, i
, cancellationToken
, TaskCreationOptions.LongRunning
, TaskScheduler.FromCurrentSynchronizationContext());
tasks[i] = r;
Thread.Sleep(Model.MSBetweenRequests);
}
Log("Done");
}
private void SubmitRequest(int reqNum)
{
Log(String.Format("{0} Started", reqNum));
Thread.Sleep(1000);
Log(String.Format("{0} Finished", reqNum));
}
private void Log(string text)
{
Results.Add(String.Format("{0}: {1}", DateTime.Now, text));
}
Obviously SubmitRequest will do something else, I was just trying to get the UI working before I put the exact details in.
|
|
|
|
|
Solved it I think.
I mentioned that I was trying the AsyncObservableCollection , apparently if I use that then I don't want to pass TaskScheduler.FromCurrentSynchronizationContext() to the task. I don't understand why (I guess a conflict somewhere)...but not sure if I need to understand either
So my ObservableCollection is now defined as:
private ObservableCollection<string> _results = new AsyncObservableCollection<string>();
public ObservableCollection<string> Results
{
get { return _results; }
set
{
_results = value;
RaisePropertyChanged("Results");
}
}
And my tasks updated the ListBox as and when they start/finish.
So I've just got to check if cancellation works, and see if I can still use WaitAll. Ideally I'd like a message when the tasks have all been started and finished (more a WhenAll (if that even exists)), at the moment I get that in the middle. But if I use WaitAll then I don't get the async updating.
Note for any others if your using .NET 4.5 then I don't think any of this is an issue as they changed the ObversableCollection.
|
|
|
|
|
Using TaskScheduler.Default or TaskScheduler.Current work when using the AsyncObservableCollection, its just FromCurrentSynchronizationContext that doesn't.
|
|
|
|