Binding to Class Item - wpf

This seems like it should be really basic but I can't seemto get it working.
I have a class file called XMLSource as follows:
Public Class XMLSource
Public Shared BrandItems As New MediaItems
Public Class MediaItems
Inherits ObservableCollection(Of MediaObject)
Implements INotifyPropertyChanged
End Class
End Class
Public Class MediaObject
Public Property Name As String
Public Property Title As String
End Class
The application reads an XML file and stores some items into XMLSource.BrandItems (happens on start-up).
I want to bind a Label control's Content property to XMLSource.BrandItems(0).Name
I tried:
<Label Content="{Binding Source={XMLSource},Path=.BrandItems[0].Src}" FontSize="20"></Label>
But it's not working.
Is it possible to bind directly like this?

You cannot contruct bindings like this, if you write {} that indicates a markup extension, further you cannot have static/shared members in a binding path. I think the correct binding would be:
{Binding [0].Src, Source={x:Static ns:XMLSource.BrandItems}}
x:Static is a markup extension which allows access of static members. (Note that this also allows access of fields unlike the Path which only allows public properties)
Where ns is declared in an xmlns attribute and points to the namespace of your XMLSource class.

Related

Hide a property from an observablecollection

So I have a WPF DataGrid bound to an ObservableCollection, which contains a single instance of a class - for example:
Public Class parent
Public Property title As String [...]
Public Property someCommonThing as Integer [...]
Public Class Child Inherits Parent
Public Property name As String [...]
Public Property address As String [...]
Public Class Window1
Dim oc As ObservableCollection(Of Object) = New ObservableCollection(Of Object)
oc.Add(New Child())
dataGrid.ItemsSource = oc
there are many child classes with different properties, hence why I can't easily define the datagrid columns directly.
I want to be able to hide certain parent properties from the datagrid (for example, never show the title property in the datagrid), while still being able to use it for databinding elsewhere (e.g. a label).
Is this possible? I can't think how to do it without manually specifying every column for every possible class instead of using the databinding.
When automatically generating columns you can change the per-property behavior using Data Annotations, in this case specifically the BrowsableAttribute class:
<Browsable(False)>
Annotating your property with this will prevent a column from being generated when using the following event handler on the AutoGeneratingColumn event of the DataGrid.
Private Sub OnAutoGeneratingColumn(sender As Object, e As DataGridAutoGeneratingColumnEventArgs)
If Not DirectCast(e.PropertyDescriptor, PropertyDescriptor).IsBrowsable Then
e.Cancel = True
End If
End Sub
Remember to add the DataAnnotations assembly to your project.

CollectionViewSource as Class Property Type

I have a Class in my main WPF application which has a Property defined in the class as follows:
Public Class AppExample
Public PropertyName As CollectionViewSource
The project solution also inherits a Class Library (separate project but included in the solution and using the Inherits statement) - in the Class Library I want to do the same thing but I get an error.
Public Class ClassLibraryExample
Public PropertyName as CollectionViewSource
this results in:
Type 'CollectionViewSource' is not defined
How do I fix this?
Add the refernce of PresentationFramework.dll to your class library. It has namespace System.Windows.Data which contains CollectionViewSource
When you are using CollectionViewSource you have to use Data namespace(System.Windows.Data).

Trying to get a WPF UserControl to Inherit a Class

I have four UserControls in my WPF Application - e.g.
VisualA, VisualB, VisualC, VisualD
I want each of them need to inherit a generic "Player" Class which contains a heap of shared code -. e.g. methods, timers etc
So far this is what I have tried in my Control's XAML
<UserControl x:Class="VisualA"
And here is what I have in a separate Class file.
Partial Public Class VisualA
Inherits Player
End Class
Public Class Player
Inherits UserControl
End Class
In my Window, I'm referencing the UserControl as normal:
<local:VisualA></local:VisualA>
But, I'm getting the following error:
Base class 'System.Windows.Controls.UserControl' specified for class
'VisualA' cannot be different from the base class 'Player' of one of
its other partial types
What am I doing wrong?
I was also under the impression any code (i.e. methods) inside the inherited class (Player) would be able to access the Controls in the UserControl by referencing by name - is that correct?
The base class in the XAML is still set to UserControl. Change it to Player. Also note that the namespace for the Player type will have to be defined. i.e:
<BaseClasses:Player x:Class="VisualA"
xmlns:BaseClasses="clr-namespace:MyProject.BaseClasses"
... all your other namespaces used

How to Add Custom Silverlight XAML Attributes?

Is it possible to introduce 'custom' attributes into different UI Elements in XAML ? Also to read them later like we add attributes for server controls in ASP.NET ?
I intend to read specific attributes and operate on them together.
It sounds like you're trying to find Attached Properties.
An attached property lets you add in a property, definable in Xaml, which can be "attached" to any UIelement. You then retrieve them in code like any other Dependency Property.
Here is the approach I tend to take with this.
Create a new class file called Meta:-
namespace SilverlightApplication1
{
public static class Meta
{
#region SomeValue
public static string GetSomeValue(DependencyObject obj)
{
return (string)obj.GetValue(SomeValueProperty);
}
public static void SetSomeValue(DependencyObject obj, string value)
{
obj.SetValue(SomeValueProperty, value);
}
public static readonly DependencyProperty SomeValueProperty =
DependencyProperty.RegisterAttached("SomeValue", typeof(string), typeof(Meta),
new PropertyMetadata(null));
#end region
#region SomeOtherValue
// Boilerplate code from above.
#end region
}
}
A value can now be attached in XAML like this:-
<TextBox x:Name="txt" local:Meta.SomeValue="Hello, World!" />
At some point in code this value can be retrieved with:-
string value = Meta.GetSomeValue(txt);
Note you don't have to stick with String as the type of the property you can pretty much use any type you like with the limitation that if you can to attach it in XAML the type must be compatible with the way XAML constructs objects (for example requires a default constructor).
The way I've accomplished that is by creating a new class that inherits the base control.
For example, I have a class called WebTextBox that inherits TextBox. And inside WebTextBox are some custom properties and events. By doing this you're inheriting all the behaviors of the TextBox control. But you can get creative here if you choose, even modifying the behavior by overriding events and such.
Anyway, after you create the class you'll then have to add the namespace for the project to the XAML. Something like this:
xmlns:me="clr-namespace:YourNamespace;assembly=YourAssembly"
And then you can add a WebTextBox (or whatever you call it) like this:
<me:WebTextBox CustomAttribute="cool stuff" />

wpf user control base class problem

I am new to WPF and have created a WPF User Control Library
I added a Base class that looks like this
public class TControl : UserControl
{
}
and want all of my controls to inherit from it.
I have a Control called Notification which looks like
public partial class Notification : TControl
{
public Notification()
{
InitializeComponent();
}
Works fine except when ever i recompile the hidden partial class where InitializeComponent() is defined gets regenerated and inherits from System.Windows.Controls.UserControl
this gives me an
Partial declarations of 'Twac.RealBoss.UserControls.Notification' must not specify different base classes
error,
is there anyway to force the generated class to inherit from my base class?
Your XAML file probably has:
<UserControl x:Class="YourNamespace.Notification" .... >
Try changing this to:
<Whatever:TControl x:Class="YourNamespace.Notification" xmlns:Whatever="clr-namespace:YourNamespace" />
The error you are getting is because the use of UserControl in the XAML tells the compiler to produce a partial class inheriting from UserControl, instead of inheriting from your class.
You can completely remove the ": TControl":
public partial class Notification : TControl
{
}
and write:
public partial class Notification
{
}
instead, since the base class is defined in the XAML part, as Paul wrote.

Resources