|
How about adding an inherited DP to the root, and using a trigger against the elements you want to hide? That way, WPF will take care of setting and resetting the visibility property on the child elements for you.
public static readonly DependencyProperty IsReportModeProperty = DependencyProperty.RegisterAttached(
"IsReportMode", typeof(Boolean), typeof(PrintLib),
new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.Inherits));
public static bool GetIsReportMode(UIElement target)
{
return (bool)target.GetValue(IsReportModeProperty);
}
public static bool SetIsReportMode(UIElement target, bool value)
{
target.SetValue(IsReportModeProperty, value);
}
<Style TargetType="{x:Type Label}">
<Style.Triggers>
<Trigger Property="ns:PrintLib.IsReportMode" Value="True">
<Setter Property="Visibility" Value="Collapsed" />
</Trigger>
</Style.Triggers>
</Style>
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
I have a view which populates tab controls as follows:
<TabControl x:Name="MyTabControl" ItemsSource="{Binding ViewModels}" Margin="4"
Background="#DCE8F3"
SelectedIndex="0"
BorderBrush="LightGray"
TabStripPlacement="Top">
<TabControl.Resources>
<DataTemplate DataType="{x:Type vm:SmartCardViewModel}">
<view:SmartCardView/>
</DataTemplate>
<DataTemplate DataType="{x:Type vm:RfidLogFileViewModel}">
<view:LogFileView/>
</DataTemplate>
<DataTemplate DataType="{x:Type vm:VideoLogFileViewModel}">
<view:LogFileView/>
</DataTemplate>
</TabControl.Resources>
<TabControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}"/>
</DataTemplate>
</TabControl.ItemTemplate>
</TabControl>
The above has been simplified for clarity.
What I want is two instances of the LogFileViewModel and LogFileView pair in the tab, one for video files and one for RFID files. However, the above does not allow me to have the same model class twice, for reasons that are fairly obvious. I have got round this by deriving classes from LogFileViewModel, called VideoLogFileViewModel and RfidLogFileViewModel, which initialise the base class appropriately. The tab control obtains the view model instances from the ViewModels property of the main view model. Hence my workaround makes sure that there are no duplicate view model class instances. However, it is inelegant.
Is there some more elegant way of doing this?
I was wondering is there is some jiggery pokery I can add to the <datatemplate> to allow it to identify a specific instance of LogFileViewModel i.e. to compare a string property with a fixed value.
|
|
|
|
|
As long as you had something in there that identifies whether the template is for RFID or for video, you can use the technique I demonstrate here[^] to switch to the appropriate template. All you need is something to trigger on.
This space for rent
|
|
|
|
|
Thanks Pete
This is probably ignorance on my part but I'm not sure how that would work with my case, since I want two instances of the same template visible at the same time, or more precisely, present at the same time since you can only view one tab at any given time. I need to think about this more!
|
|
|
|
|
You're using two separate ViewModel instances - the appropriate template will be rendered in place based off the ControlTemplate.
This space for rent
|
|
|
|
|
I was developing WPF Desktop App with several features. One of them was recording video into file from webcam(usb). I used AForge.NET Framework for implementing this. Everything was fine till we try to play saved videos in HTML5 media player. Supported video codecs by the player are not supported by AForge. AForge seems not to be a live project anymore. So I tried to recompile by myself the latest source code from AForge with suggested patches (include H.264) I found on the internet. But without any luck. I guess I have to look for any other solution instead of using AForge.
I am really confused I could not find any helpful information on the internet about recording video from C# (WPF). Maybe I am so strictly oriented the way AForge is working that I am not able to find any other types of solution anymore.
After one day spent on the internet I found out:
There is no way supported directly by Microsoft for WPF application to capture video into file (h264). The only useful Microsoft SDK for this kind features is supported just by WindowsPhone or Silverlight platforms. So to implement it I still have to use third party frameworks. There is a Project iSpyConnect similar to AForge and is still living. Maybe I can look for inspiration in there
Can anybody help please, to suggest me any kind of solution? It seems nobody needs to capture webcam video from WPF App since I could find on the internet just articles mostly older than 2013 for this theme
|
|
|
|
|
The MS Expression Encoder SDK v4 can save to some 18 different presets of H264; it is not limited to Silverlight or streaming; this is because the "pro" version required for expanded H264 functionality is the only version now available and is free (including Encoder 4 itself).
(The samples appear to include elements of what you are looking for).
|
|
|
|
|
Summary:
Designer "Cannot create an instance of [UserControl]" due to not being able to find the style resource file the user-control uses, linked from within the user-control. However, the user-control itself is displayed correctly in designer, and, the user control is displayed properly when the project is built and running.
Details:
I've decided to put some sense into my project structure and moved XAML resource files under /Resources/ directory in my project.
I have a user control that resides in /UserControls/ which looks for a resource file from /Resources/GeneralTheme.xaml which is also used by the parent window. All Source properties look like Source="/Resources/GeneralTheme.xaml"
What didn't work:
*Moving just the UserControl.xaml to the root.
*Using pack://application:,,,/Resources/GeneralTheme.xaml instead of the plain alternative.
What works:
*A completely flat project structure, aka put everything under the root.
But I don't like the latter choice.
Here's how I reference my user control inside the parent window:
<UserControls:SQLFilterSettings DataContext="{Binding Path=Criteria}"/>
Here's how I reference the resource file in the User-Control xaml:
<ResourceDictionary Source="/Resources/UserControlResources.xaml" />
Any help is much appreciated!
|
|
|
|
|
I am (I have to) using an XAML file as a resource from my main window.
In this simplified example, the XAML file looks like this
<Grid xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Name="themeGrid">
<Image Height="Auto" HorizontalAlignment="Left" Margin="0" Stretch="Fill" VerticalAlignment="Top" Width="Auto">
<Image.Source>
<BitmapImage UriSource="pack://siteoforigin:,,,/Resources/image1.jpg" CacheOption="OnLoad" />
</Image.Source>
</Image>
</Grid>
The file is loaded that way (the XAML file, as well as a 'image1.jpg' file, are in a 'Resources' folder along with the exe file)
Imports System.IO
Class MainWindow
Private Sub MainWindow_Loaded(sender As Object, e As System.Windows.RoutedEventArgs) Handles Me.Loaded
loadInterface()
End Sub
Sub loadInterface()
Dim GridUri As String = System.AppDomain.CurrentDomain.BaseDirectory & "Resources\theme.xaml"
Dim fs As FileStream = New FileStream(GridUri, FileMode.Open, FileAccess.Read)
Dim sri = TryCast(System.Windows.Markup.XamlReader.Load(fs), Grid)
Me.Content = sri
fs.Close()
End Sub
End Class
..and that works nicely
Now I would like to use a label whit a font file taken in the same 'Resources' folder (the font used in this example: http://www.dafont.com/fr/digital-7.font)
<Grid xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Name="themeGrid">
<Image Height="Auto" HorizontalAlignment="Left" Margin="0" Stretch="Fill" VerticalAlignment="Top" Width="Auto">
<Image.Source>
<BitmapImage UriSource="pack://siteoforigin:,,,/Resources/image1.jpg" CacheOption="OnLoad" />
</Image.Source>
</Image>
<Label FontFamily="pack://siteoforigin:,,,/Resources/#Digital-7" Content="Have a nice day!"/>
</Grid>
...but then the label text isn't displayed with the proper FontFamily!
What should I please do for the text of the label to be displayed using the font in the resources folder?
Thanks very much!!
PS: the font file CAN'T be in resource of the application. Think of this XAML as a theme, any font could be inside and the application couldn't have all those possible fonts in resources!
|
|
|
|
|
You can always include the font as a content item. All you need to do is make sure that the font is available in the application directory. If you do this, you can then reference it like this:
<Label FontFamily="#Digital-7" Content="Have a nice day!" />
This space for rent
|
|
|
|
|
I like to create a Combobox with multi column header if the Combobox is open but if i close the box only one column should be displayed.
In Forms it's very simple but in WPF i have no solution.
Either i have multi column header or i have one column in the closed Combobox but I can't get both together.
Maybe some one have a solution for me.
|
|
|
|
|
Google has lots of suggestions[^]. For example, WPF Multicolumn Combobox - Stack Overflow[^].
In particular, if you change the ItemContainerStyle , rather than the ItemTemplate , and set the DisplayMemberPath appropriately, then you'll get a single column in the closed box, and multiple columns in the drop-down.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Thanks, it's working
I was on the wrong way with ItemTemplate.
|
|
|
|
|
Hi all.
In xaml, which properties i need to override to get MouseEnter, MouseLeave and IsSelected to do nothing visually in a listview. I mean change the default style by one that don't do nothing.
Thanks
|
|
|
|
|
Hi,
i am looking for a simple example or orientations on how to use Grouping in virtualized datagrid in code
i have setup a wpf toolkit virtualized datagrid with entity framework and a DataGridVirtualizingCollectionViewSource by handling the QueryItems and the QueryItemCount events, and it work just fine .
now i want to add groups at runtime by code, but i didn't find any sample on how to do that .
is the QueryGroups event is what i have to implmement ? , if yes how ?
i have asked in the toolkit forum on codeplex for more than a month but got no response, so any help or orientation is welcome .
thanks and good day.
|
|
|
|
|
Stop spamming the forums with your question. You have already been told that you post in one place - and Window Forms has nothing to do with WPF or Silverlight.
This space for rent
|
|
|
|
|
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.
|
|
|
|
|