|
Reposting the same demand for code every few days because nobody has done your work for you yet is considered abuse. Keep it up, and you'll be kicked off this site.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
This isn't even a question. It's ironic that someone so lazy that cannot even type a question would post the same non-question multiple times.
There are only 10 types of people in the world, those who understand binary and those who don't.
|
|
|
|
|
Good Day all
i am using Navigation service as depicted below
<Frame x:Name="_home" NavigationUIVisibility="Hidden" HorizontalAlignment="Stretch" Width="2749" Margin="0,12,0,0" />
and i navigate to the Page like this
(Application.Current.MainWindow.FindName("_home") as Frame).Source = new Uri("/F1.xaml", UriKind.Relative);
which work fine. now in the Navigated page, lets just say a page shown in the Frame,there is some functionality like Calculate ,e.g that calculates Age based on the years(Example). Now from the Main Page i have a Button that says Calculate , i want to call the function or invoke a button click of Frame page from the Main Page.
Well i have tried this from the main page
<pre lang="c#">private void btnCalculate_Click(object sender, RoutedEventArgs e)
{
F1 f1 = new F1();
f1.CalculateYear();
}</pre>
no but does not work, the break-point does reach the F1 page but the UI does not have calculated results.
One other thing i tried earlier is to pass the value that will be used in the calculation from the main , but when the one follow the variable value they just return an empty string when you follow it while stepping through it.
How is this done
Thanks
Vuyiswa Maseko,
Spoted in Daniweb-- Sorry to rant. I hate websites. They are just wierd. They don't behave like normal code.
C#/VB.NET/ASP.NET/SQL7/2000/2005/2008
http://www.vimalsoft.com
vuyiswa[at]vimalsoft.com
|
|
|
|
|
Found a Solution
Changed this
F1 f1 = new F1();
to this
F1 f1 = (F1 )_home.Content;
Vuyiswa Maseko,
Spoted in Daniweb-- Sorry to rant. I hate websites. They are just wierd. They don't behave like normal code.
C#/VB.NET/ASP.NET/SQL7/2000/2005/2008
http://www.vimalsoft.com
vuyiswa[at]vimalsoft.com
|
|
|
|
|
I created a standard VisualHost control that just shows a circle at a given location. I combined this with the ability to host a UserControl in the same class, so I could easily switch between a basic edition view that just showed a circle and a more advanced view that showed a UserControl instead.
After a bit I came up with this:
using System;
using System.Windows;
using System.Windows.Media;
using System.ComponentModel;
using System.Windows.Input;
namespace WpfPrismTests
{
public class CanvasPoint : FrameworkElement, INotifyPropertyChanged
{
private VisualCollection _children;
#region "Constructors"
public CanvasPoint()
{
_children = new VisualCollection(this);
_children.Add(CreateDrawingVisualCircle());
}
protected override void OnMouseEnter(MouseEventArgs e)
{
base.OnMouseEnter(e);
}
public CanvasPoint(Point p_position)
{
PositionOnCanvas = p_position;
_children = new VisualCollection(this);
_children.Add(CreateDrawingVisualCircle());
}
#endregion
private DrawingVisual CreateDrawingVisualCircle()
{
DrawingVisual drawingVisual = new DrawingVisual();
DrawingContext drawingContext = drawingVisual.RenderOpen();
drawingContext.DrawEllipse(BackgroundColor, new Pen(BackgroundColor, 1.0), PositionOnCanvas, 4, 4);
drawingContext.Close();
return drawingVisual;
}
#region "Dependency Properties"
public static DependencyProperty ShowContentProperty = DependencyProperty.Register("ShowContent",
typeof(bool), typeof(CanvasPoint), new PropertyMetadata(false, OnShowContentPropertyChanged));
public bool ShowContent
{
get
{
return (bool)this.GetValue(ShowContentProperty);
}
set
{
this.SetValue(ShowContentProperty, value);
}
}
private static void OnShowContentPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
bool value = (bool)e.NewValue;
CanvasPoint thisElement = d as CanvasPoint;
if (value)
{
thisElement.AddLogicalChild(thisElement.Content);
}
else
{
thisElement.RemoveLogicalChild(thisElement.Content);
}
}
private static FrameworkPropertyMetadata ContentMetadata =
new FrameworkPropertyMetadata(null,
FrameworkPropertyMetadataOptions.BindsTwoWayByDefault);
public static readonly DependencyProperty ContentProperty =
DependencyProperty.RegisterAttached("Content", typeof(UIElement),
typeof(CanvasPoint), ContentMetadata);
public UIElement Content
{
get
{
return (UIElement)this.GetValue(ContentProperty);
}
set
{
this.SetValue(ContentProperty, value);
}
}
#endregion
#region "Properties"
private Point p_PositionOnCanvas = new Point();
public Point PositionOnCanvas
{
get { return p_PositionOnCanvas; }
set
{
p_PositionOnCanvas = value;
INotifyChange("PositionOnCanvas");
}
}
private SolidColorBrush pBackgoundColor = Brushes.Red;
public SolidColorBrush BackgroundColor
{
get { return pBackgoundColor; }
set
{
pBackgoundColor = value;
_children.Clear();
_children = new VisualCollection(this);
_children.Add(CreateDrawingVisualCircle());
}
}
#endregion
#region "Overided properties"
protected override int VisualChildrenCount
{
get
{
if (this.ShowContent)
{
UIElement childElement = (UIElement)GetValue(ContentProperty);
return childElement != null ? 1 : 0;
}
else
{
return _children.Count;
}
}
}
protected override Visual GetVisualChild(int index)
{
if (this.ShowContent)
{
return (UIElement)GetValue(ContentProperty);
}
else
{
if (index < 0 || index >= _children.Count)
{
throw new ArgumentOutOfRangeException();
}
return _children[index];
}
}
protected override Size MeasureOverride(Size availableSize)
{
UIElement childElement = (UIElement)GetValue(ContentProperty);
if (childElement != null)
childElement.Measure(availableSize);
return availableSize;
}
protected override Size ArrangeOverride(Size finalSize)
{
UIElement childElement = (UIElement)GetValue(ContentProperty);
if (childElement != null)
{
Rect ChildSize = new Rect(new Point(0, 0), finalSize);
double CenterX = ChildSize.Width / 2;
double CenterY = ChildSize.Height / 2;
childElement.Arrange(new Rect(new Point(-CenterX + PositionOnCanvas.X, -CenterY + PositionOnCanvas.Y), finalSize));
}
return finalSize;
}
#endregion
public event PropertyChangedEventHandler PropertyChanged;
protected void INotifyChange(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
}
}
This works, but I do wonder why the CanvasPoint insisted that the point 0,0 was located in the center of the host control, so I had to adjust the position accordingly:
protected override Size ArrangeOverride(Size finalSize)
{
UIElement childElement = (UIElement)GetValue(ContentProperty);
if (childElement != null)
{
Rect ChildSize = new Rect(new Point(0, 0), finalSize);
double CenterX = ChildSize.Width / 2;
double CenterY = ChildSize.Height / 2;
childElement.Arrange(new Rect(new Point(-CenterX + PositionOnCanvas.X, -CenterY + PositionOnCanvas.Y), finalSize));
}
return finalSize;
}
The second and the real problem is that events in the user control, as Mouse over etc. , won't work with the hosted control, but works with the DrawingContext.Ellipse. What is the problem here?
|
|
|
|
|
Probably not the answer you are looking for, but I would replace all that code with an Ellipse and a User Control hosted in the same cell of a Grid; and just toggle their Visibility.
|
|
|
|
|
Yes, that would solve the problem. But I have a feeling that I'm missing something here that I should have known. Why does my code show the UserControl, but disable all interaction with it or the parent control?
[Edit]
I get the feeling that I have just printed out the control to a static visual?
[/Edit]
modified 13-Jan-16 8:22am.
|
|
|
|
|
The recommended approach to custom control development is that it be considered last relative to solutions using user controls and / or templates.
|
|
|
|
|
I have basically just copied the approach found here[^]. I just made some minor adjustments and wrapped the functionality inside a CustomControl:
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
public class MyCanvas : Canvas
{
public static DependencyProperty ItemsSourceProperty =
DependencyProperty.Register("ItemsSource",
typeof(IEnumerable), typeof(MyCanvas),
new FrameworkPropertyMetadata((IEnumerable)null,
new PropertyChangedCallback(OnItemsSourcePropertyChanged)));
private static Dictionary<INotifyCollectionChanged, MyCanvas> references = new Dictionary<INotifyCollectionChanged, MyCanvas>();
public IEnumerable ItemsSource
{
get
{
return (IEnumerable)this.GetValue(ItemsSourceProperty);
}
set
{
this.SetValue(ItemsSourceProperty, value);
}
}
private static void OnItemsSourcePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var canvas = d as MyCanvas;
repopulateChildren(canvas);
if (canvas.ItemsSource is CompositeCollection)
{
CompositeCollection CollectionHolder = ((CompositeCollection)canvas.ItemsSource);
foreach (CollectionContainer item in CollectionHolder)
{
ObservableCollection<UIElement> elements = (ObservableCollection<UIElement>)item.Collection;
references.Add((elements as INotifyCollectionChanged), canvas);
elements.CollectionChanged -= collectionChangedHandler;
elements.CollectionChanged += collectionChangedHandler;
}
}
else if (canvas.ItemsSource is IEnumerable<UIElement>)
{
var be = BindingOperations.GetBindingExpression(canvas, MyCanvas.ItemsSourceProperty);
if (be != null)
{
var elements = (be.ResolvedSourcePropertyName == null ? be.ResolvedSource :
be.ResolvedSource.GetType().GetProperty(be.ResolvedSourcePropertyName).GetValue(be.ResolvedSource)) as INotifyCollectionChanged;
if (elements != null)
{
var cv = references.FirstOrDefault(i => i.Value == canvas);
if (!cv.Equals(default(KeyValuePair<INotifyCollectionChanged, MyCanvas>)))
references.Remove(cv.Key);
references[elements] = canvas;
elements.CollectionChanged -= collectionChangedHandler;
elements.CollectionChanged += collectionChangedHandler;
}
}
else references.Clear();
}
}
private static void collectionChangedHandler(object sender, NotifyCollectionChangedEventArgs e)
{
MyCanvas cv;
if (references.TryGetValue(sender as INotifyCollectionChanged, out cv))
{
switch (e.Action)
{
case NotifyCollectionChangedAction.Add:
foreach (var item in e.NewItems) cv.Children.Add(item as UIElement);
break;
case NotifyCollectionChangedAction.Remove:
{
foreach (var item in e.OldItems)
{
cv.Children.Remove(item as UIElement);
}
break;
}
case NotifyCollectionChangedAction.Reset:
repopulateChildren(cv);
break;
}
}
}
public static DependencyProperty PerservedChildrenProperty = DependencyProperty.Register("PerservedChildren", typeof(int), typeof(MyCanvas), new PropertyMetadata(0));
public int PerservedChildren
{
get
{
return (int)this.GetValue(PerservedChildrenProperty);
}
set
{
this.SetValue(PerservedChildrenProperty, value);
}
}
private static void repopulateChildren(MyCanvas cv)
{
for (int i = cv.Children.Count - 1; i >= cv.PerservedChildren; i--)
{
cv.Children.RemoveAt(i);
}
var elements = (IEnumerable)cv.GetValue(ItemsSourceProperty );
if (elements is CompositeCollection)
{
CompositeCollection CollectionHost = ((CompositeCollection)elements);
foreach (CollectionContainer item in CollectionHost)
{
foreach (UIElement pp in item.Collection)
{
if (!(cv.Children.Contains(pp)))
cv.Children.Add(pp);
}
}
}
else if (elements is IEnumerable<UIElement>)
{
foreach (UIElement elem in elements)
{
cv.Children.Add(elem);
}
}
}
}
I can now bind an ObservableCollection<uielement> directly to the ItemsSource and it will work properly.
The problem appeared when I wanted to create support binding a CompositeCollection to it as well. The problem seems to be that I can't find the appropriate instance of the MyCanvas in the Dictionary, as it will only delete points found in one of the CollectionContainers bounded to the CompositeCollection. What am I missing here?
I did try and look at the ItemControl posted at Reference Source[^] since it seems to have support for CollectionContainers out of the box. I do realize that I can use an ItemControl to bind items to a canvas as well WPF Canvas, how to add children dynamically with MVVM code behind - Stack Overflow[^], and that could solve my problem, but I want to know how to make my code work with CollectionContainers.
|
|
|
|
|
Well I did find a solution to my own question:
public class MyCanvas : Canvas
{
private static MyCanvas ThisCanvas;
public MyCanvas()
{
ThisCanvas = this;
}
...
}
Now I can call ThisCanvas from all static voids, but I'm curious as to how many instances will share this value?
|
|
|
|
|
Kenneth Haugland wrote: how many instances will share this value?
All of them. The value in a static field is shared across the whole AppDomain *.
Wouldn't it be simpler to get rid of the references dictionary, and make your collectionChangedHandler method an instance method?
Something like this should work:
private static void OnItemsSourcePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var canvas = (MyCanvas)d;
canvas.OnItemsSourcePropertyChanged(e);
}
protected virtual void OnItemsSourcePropertyChanged(DependencyPropertyChangedEventArgs e)
{
repopulateChildren(this);
var compositeCollection = e.OldValue As CompositeCollection;
if (compositeCollection != null)
{
foreach (CollectionContainer item in compositeCollection)
{
var elements = (ObservableCollection<UIElement>)item.Collection;
elements.CollectionChanged -= collectionChangedHandler;
}
}
else
{
var elements = e.OldValue as INotifyCollectionChanged;
if (elements != null)
{
elements.CollectionChanged -= collectionChangedHandler;
}
}
compositeCollection = e.NewValue As CompositeCollection;
if (compositeCollection != null)
{
foreach (CollectionContainer item in compositeCollection)
{
var elements = (ObservableCollection<UIElement>)item.Collection;
elements.CollectionChanged += collectionChangedHandler;
}
}
else
{
var elements = e.NewValue as INotifyCollectionChanged;
if (elements != null)
{
elements.CollectionChanged += collectionChangedHandler;
}
}
}
private void collectionChangedHandler(object sender, NotifyCollectionChangedEventArgs e)
{
...
}
* Unless the field is marked with the ThreadStatic attribute[^], in which case it's specific to a thread. But that wouldn't help you in this case.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Ah, yes, I didn't like the static value or Dictionary either, so I ended up using a delegate instead:
elements.CollectionChanged -= (sender, ee) => MyCollectionChangedHandler(cv, sender, ee);
private static void MyCollectionChangedHandler(MyCanvas cv, object sender, NotifyCollectionChangedEventArgs e)
I also thought they static members were shared everywhere in the application, but I made the attached property code below:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
namespace MyApplication
{
public static class TextBoxUpdateExplicitBinding
{
private static TextBox tb;
private static List<TextBox> MyList;
static TextBoxUpdateExplicitBinding()
{
MyList = new List<TextBox>();
}
#region "UpdateSourceOnKeyProperty"
public static readonly DependencyProperty UpdateSourceOnKeyProperty =
DependencyProperty.RegisterAttached(
"UpdateSourceOnKey",
typeof(Key),
typeof(TextBoxUpdateExplicitBinding),
new FrameworkPropertyMetadata(Key.None, KeyChanged));
public static void SetUpdateSourceOnKey(UIElement element, Key value)
{
element.SetValue(UpdateSourceOnKeyProperty, value);
}
public static Key GetUpdateSourceOnKey(UIElement element)
{
return (Key)element.GetValue(UpdateSourceOnKeyProperty);
}
private static void KeyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
tb = (TextBox)obj;
if (!MyList.Contains(tb))
{
MyList.Add(tb);
tb.PreviewKeyDown += TextBoxKeyDown;
}
}
#endregion
static void TextBoxKeyDown(object sender, KeyEventArgs e)
{
tb = (TextBox)sender;
if (tb == null) return;
var propertyValue = (Key)tb.GetValue(UpdateSourceOnKeyProperty);
if (e.Key != propertyValue) return;
var bindingExpression = tb.GetBindingExpression(TextBox.TextProperty);
if (bindingExpression != null) bindingExpression.UpdateSource();
}
public static DependencyProperty BindProperty = DependencyProperty
.RegisterAttached("Bind",
typeof(bool),
typeof(TextBoxUpdateExplicitBinding),
new PropertyMetadata(AttachCommand));
public static void SetBind(DependencyObject d, bool command)
{
d.SetValue(BindProperty, command);
}
private static void AttachCommand(DependencyObject d,
DependencyPropertyChangedEventArgs e)
{
(d as Button).Click += Button_Click;
}
private static void Button_Click(object sender, RoutedEventArgs e)
{
var bindingExpression = tb.GetBindingExpression(TextBox.TextProperty);
if (bindingExpression != null) bindingExpression.UpdateSource();
}
}
}
I now used this in a separate user contol:
<TextBox x:Name="tb" Grid.Column="0" local:TextBoxUpdateExplicitBinding.UpdateSourceOnKey="Return"
Text="{Binding RelativeSource={RelativeSource AncestorType={x:Type local:SearchControl}},
Path=SearchText,
UpdateSourceTrigger=Explicit,
Mode=OneWayToSource }"/>
<Button Grid.Column="1" local:TextBoxUpdateExplicitBinding.Bind="True" >
<ContentControl>
<Image Source="pack://application:,,,/Icons/Search.png" Height="20" Width="20"/>
</ContentControl>
</Button>
And if I now added several of this user control in the same window, they didnt seem to share the static values in the attatched property. That's why I wondered.
|
|
|
|
|
Hey all, I have done UITests on Android, iOS, and Windows 10 apps, but now I have to develop and app that needs desktop support too. WPF seems to be the best way to support < Windows 10 devices to me, but I am interested if I Microsoft provides a library I can use to run UITests on a WPF application? Are there any libraries like this?
i cri evry tiem
|
|
|
|
|
|
Good Day
i have a code which is fired on the Button click even
Status.Background = new SolidColorBrush(Colors.Orange);
Status.Content = "Exporting, please wait...";
Logger.ExportLogToExcel();
Status.Background = new SolidColorBrush(Colors.Yellow);
Status.Content = "Exported to Excel Successfully";
What is Part 1 not working. Basically , i am Exporting to Excel , and i am changing the Label that shows the status, i am changing the color and also the contents. but the Dont change i only see "Exported to Excel Successfully"
I thought might be that the Export is quick to a point that it immediately jump to Success message. i added a thread to make to sleep for a few seconds before it can export so i see a different background.
Thanks
Vuyiswa Maseko,
Spoted in Daniweb-- Sorry to rant. I hate websites. They are just wierd. They don't behave like normal code.
C#/VB.NET/ASP.NET/SQL7/2000/2005/2008
http://www.vimalsoft.com
vuyiswa[at]vimalsoft.com
|
|
|
|
|
I am guessing that everything is done on the main thread so the UI thread locks until the method is completed and the last colour change is effected.
Unless you do the export on a separate thread you are not going to see the initial colour change. putting in a delay does not help, move the export to a BGW thread.
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
i actually tried that initially. by setting the color from another Thread and the Export is obviously in another thread. but still the issue remains , let me keep trying something will post the feedback if i get to the solution.
Vuyiswa Maseko,
Spoted in Daniweb-- Sorry to rant. I hate websites. They are just wierd. They don't behave like normal code.
C#/VB.NET/ASP.NET/SQL7/2000/2005/2008
http://www.vimalsoft.com
vuyiswa[at]vimalsoft.com
|
|
|
|
|
No no no, you set the colour BEFORE you launch the BGW that exports the excel, in the BGW compleate method you set the colour the second time.
This allows the UI to refresh while the BGW is working.
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
You are 100% Right, i was missing Something. its now working like charm.
Vuyiswa Maseko,
Spoted in Daniweb-- Sorry to rant. I hate websites. They are just wierd. They don't behave like normal code.
C#/VB.NET/ASP.NET/SQL7/2000/2005/2008
http://www.vimalsoft.com
vuyiswa[at]vimalsoft.com
|
|
|
|
|
- How do you unit test a piece of UI becoming visible/invisible? The bound bool may be correct, but the converter could fail.
- How do you unit test data validations?
If it's not broken, fix it until it is
|
|
|
|
|
Kevin Marois wrote: How do you unit test a piece of UI becoming visible/invisible? The bound bool may be correct, but the converter could fail. If you're that worried about the converter, you would write a UI automation test. However, a better bet would be to write a unit test for your converter to ensure it responds to changes (this is assuming you aren't using the standard visibility converter for some reason - but why would that one fail).
Kevin Marois wrote: How do you unit test data validations? Again, you test the underlying logic. If you are worried about UI behaviour, write UI automation tests.
This space for rent
|
|
|
|
|
Thanks.
I'm trying to write units tests to test acceptance criteria, and some of states "When this is true then this UI part should visible".
So it's not really about the converter as much as it is aligning tests with acceptance with the idea being that after any form of refactoring, the UI part is still respecting the condition.
If it's not broken, fix it until it is
|
|
|
|
|
In which case, a Coded Unit Test[^] is probably going to be your best bet.
This space for rent
|
|
|
|
|
Pete O'Hanlon wrote: (this is assuming you aren't using the standard visibility converter Where be this standard converter!
I have a bunch of converters that I call standard I did not know there are built in converters!
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
System.Windows.BooleanToVisibilityConverter. There are other converters that do things for you behind the scenes such as this[^] puppy.
This space for rent
|
|
|
|
|