WPF Databinding to Custom Collection Objects - wpf

Public Sub New(ByVal log As Entities.LogSystem)
InitializeComponent()
Me.DataContext = log
End Sub
This is the the initializer for my custom control It passes in a single entity that has several property fields. This control is added to a parent control so that it appears in a stackpanel.
Anyway I am trying to get the specific data from this control into several different text boxes:
<UserControl x:Class="LogSystemPickerItem"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WavelengthIS.WISRED.UserControls"
Width="579" Height="122">
<UserControl.Resources>
<local:LogSystemPickerItem x:Key="Log"/>
</UserControl.Resources>
<Grid DataContext="{Binding Source={StaticResource Log}}">
<Label Height="30" Name="Label1" VerticalAlignment="Top" Content="{Binding deptDescription}"/>
</Grid>
</UserControl>
As you can see i havent really gotten too far. I have tried many different ways to do this including using dependency properties...I just really cant find a tutorial that shows this specific circumstance...can anyone point me in the right direction?

If you're setting the DataContext in the code behind as per your first code snippet, there's no need to also do it in the XAML, so you can remove the "Log" resource and the corresponding DataContext assignment on the Grid.
Once you've done that, it should work assuming there is a deptDescription property on your log class.

... and in XAML you may do it this way...
<UserControl.DataContext>
<local:LogSystemPickerItem/>
</UserControl.DataContext>

Related

User control that opens dialog, where dialog result updates properties in viewmodel of the page that uses it

I have been struggling with this question for some time now. It seems relatively simple, but I am unsure of how to solve it. Would love your aid on this.
I have a page that's bound to viewmodel, that has some string properties that represent file paths.
I've built a user control that has a textbox and a button. The control's purpose: show a dialog when you click on the button(file dialog), and update the textbox according to the result.
Here is the xaml:
<UserControl x:Class="MyProject.Controls.FilePickerLauncherControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
x:Name="me"
d:DesignHeight="300" d:DesignWidth="300">
<DockPanel>
<Button Content="..." DockPanel.Dock="Right" Command="{Binding OpenFileDialogCommand,ElementName=me}"></Button>
<TextBox Text="{Binding Path=PathChosen,ElementName=me}" DockPanel.Dock="Right" VerticalAlignment="Center" Height="30"></TextBox>
</DockPanel>
This is my the command in page's view model(the action):
private void OpenFileExplorer()
{
SimpleIoc.Default.GetInstance<IInputOutputService>().OpenFileDialog(modelsDirectory);
}
Now what I want to do, for every instance of my control, to take the result of the dialog and put it in the textbox that's in the control. I've been thinking of:
maybe a command parameter that would be sent to this OpenFileExplorer, telling which property should be updated somehow, but I am not sure how.
Write this command multiple times for each property. I don't think this is correct.
Create a new viewmodel for my control with this command and make instances of it in my current view model.
What would you guys say the best way to do this? it is relatively simple, although it got me kind of confused.

WPF - MVVM Command binding on Sub ViewModel

I've got a VehicleViewModel that has a sub ViewModel of NotesViewModel
public IManageVehicleNotesViewModel NotesViewModel { get; set; }
On the first activation of VehicleViewModel I activate the sub ViewModel.
NotesViewModel.Activate();
The activation calls a method to init a number of Commands, I've break pointed this and its being called.
CreateCommand = new DelegateCommand<object>(OnCreateCommand, CanCreate);
However although the TextBoxes are binding on the sub View (so the DataContext is in place) none of the commands are binding - I've tried to calling RaiseCanExecuteChanged on the commands but they don't disable, enable or call the methods as expected.
I don't know whether its relevant (as the TextBoxes are binding) but I'm associating the View and ViewModel using a ResourceDictionary as so ...
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:v="clr-namespace:GTS.GRS.N3.Modules.Vehicles.Views"
xmlns:vm="clr-namespace:GTS.GRS.N3.Modules.Vehicles.Model">
<DataTemplate DataType="{x:Type vm:ManageVehicleViewModel}">
<v:ManageVehicleView />
</DataTemplate>
<DataTemplate DataType="{x:Type vm:ManageVehicleNotesViewModel}">
<v:ManageVehicleNotesView />
</DataTemplate>
</ResourceDictionary>
The commands on the top level VehicleViewModel work.
Has anyone experienced anything like this? Is it the order I'm doing things? Any help gratefully received!
Cheers,
Andy
Does the CreateCommand property trigger the PropertyChanged event ? If it doesn't, the UI won't be notified when you assign it...
Try to use a tool like Snoop to check whether the Command property of the button is set
Do this and check the output to see what is going on:
<UserControl …
xmlns:diagnostics="clr-namespace:System.Diagnostics;assembly=WindowsBase" />
<Button Command="{Binding MyCommand,
diagnostics:PresentationTraceSources.TraceLevel=High}" … />
It should report what object it's actually trying to bind to, etc. Check your output window while you are running to see what is going on with that binding.

ListBox always auto selects first item

ListBox's behavior is that the first item is selected automatically, how can I avoid that??
Note: I prefer to do this with pure xaml, if you have any code-behind ideas then please don't bother yourself.
Try
IsSynchronizedWithCurrentItem="False"
Well i tried this using FocusManager.FocusedElement .. and made the intial focus to
listbox itself.. so it has the focus..but no element is selected..
if u press down or tab ..the 1st element of the listbox will be selected...
<Window
......
FocusManager.FocusedElement="{Binding ElementName=listbox2}">
<ListBox x:Name="listbox2" HorizontalAlignment="Left"
VerticalAlignment="Bottom" Width="117.333" Height="116"
Margin="30.667,0,0,30">
<ListBoxItem>Jim</ListBoxItem>
<ListBoxItem>Mark</ListBoxItem>
<ListBoxItem>Mandy</ListBoxItem>
</ListBox>
remove IsSynchronizedWithCurrentItem="True" an add it with the next SelectionChanged event if needed.
This solved my problem
You could set SelectedIndex to -1 :
<ListBox ItemsSource="{Binding MyData}" SelectedIndex="-1"/>
Note: I want to do this with pure xaml, if you have any code-behind ideas then please don't bother yourself.
Unfortunately you can't do everything in XAML... you can usually avoid code-behind, but you still need to write converters, markup extensions or attached properties
Here's a technique I use quite often. It builds on the above example of adding the FocusedElement attribute to your Window or UserControl.
My deal is that I don't want ANY of the controls on my window to have focus. The solution for me is to create a dummy control that has no UI and assign focus to that. It just so happens that Control fits the bill perfectly:
<UserControl
x:Class="MyControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
FocusManager.FocusedElement="{Binding ElementName=focus_thief}"
mc:Ignorable="d">
<Grid>
<!-- no renderable UI -->
<Control Name="focus_thief"/>
<!-- wants focus, but won't get it -->
<ListBox>
<ListBoxItem>First Item</ListBoxItem>
</ListBox>
</Grid>
</UserControl>
<ListBox SelectioMode="Single" SelectedIndex="-1"/>
Is SelectedIndex the property you're looking for ? Or maybe I don't get your point...
Same issue here. Anyone found a "clean" solution?
The problem is the same here, it causes a bunch of triggers to execute.
Obvious solution/fix:
Remove SelectionChanged event handlers from XAML
Add handlers in the constructor after InitializeComponents has loaded the listbox.
Add a blank item.

DependencyProperty: VS cannot find the source for binding

I'm trying to bind the Forderground dependency property to my UIControl, so that it's drawn in the color the user wishes. Since myUiControl.Foderground autocopletes, I thought I could just bind it in the XAML file like this:
{Binding ElementName=rootControl, Path=Forderground}
When debugging VS says it cannot find the source for binding with this DependencyProperty.. but I couldn't figure out why this is.
Also how can I list all dependency properties of an object while debugging?
UPDATE: If below wasn't enough for you, try downloading this sample and looking at it.
The ElementName needs to be set as the "x:Name" of your root control and the Path needs to be set to the Property on the root element you wish to bind to. Without the name it cannot find the element you are referring to (hence the initial error) and without the Path it doesn't bind to the correct property (check your output at runtime for an error).
Try this:
<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Grid x:Name="root" Background="Green">
<Button Background="White" Margin="100">
<TextBlock Background="{Binding ElementName=root, Path=Background}" Text="TESTING TESTING"/>
</Button>
</Grid>
Can you confirm that your "rootControl" element is defined earlier in the xaml markup than your Binding holder? Usually the Bindings are bound to the earlier declared elements.
If you mean ImmediateWindow and IntelliSense usage while debugging than each dependency property metadata has usually public static access modifiers. You can for instance type "Control." and observe all the corresponding dependency properties, routed events and attached properties members.
Hope this helps.

Reference Access database dataset.designer file in WPF?

Hey, I've included an MS Access database in my WPF VB app, and I'm trying to link the data to an XCEED Datagrid. I have the following code in my testerDataSet.Designer.vb file which I assume is the funcion I should be referencing
Public ReadOnly Property Contact() As ContactDataTable
Get
Return Me.tableContact
End Get
End Property
I'm trying to get it to fill my datagirid using this
<Grid.Resources>
<xcdg:DataGridCollectionViewSource x:Key="cvs_contacts" Source="{Binding Path=Contact, *Source={x:Static testerDataSet}*}"/>
</Grid.Resources>
<xcdg:DataGridControl Margin="54,18,4,3" Name="DataGridControl1" ItemsSource="{Binding Source={StaticResource cvs_contacts}}"/>
Unfortunately the bolded/stared part is givi ng me errors, does anyone know the correct code i should be using here to reference my source?
Thanks guys!
EDIT: Okay let me try and outline what I've done... I've added an Access 2007 Database called "tester" to my project as an existing item, and VS has gone and made testerDataSet for me, and inside testerDataset.Designer.vb I assume the first code above is the code i need to display my table data.
Basically my entire code for Window1.xaml is as follows (its just a test project to see If I can actually get the database working)
<Window x:Class="Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="369" Width="503" xmlns:xcdg="http://schemas.xceed.com/wpf/xaml/datagrid">
<Grid>
<Grid.Resources>
<xcdg:DataGridCollectionViewSource x:Key="cvs_contacts" Source="{Binding Path=Contact, Source={StaticResource testerDataSet}}"/>
</Grid.Resources>
<xcdg:DataGridControl Margin="54,18,4,3" Name="DataGridControl1" ItemsSource="{Binding Source={StaticResource cvs_contacts}}"/>
</Grid>
What I'm trying to achieve is for the datagrid to display the data in the Contact datatable. I'm probably missing something important here (I'm quite new to coding =/ ) To be perfectly honest I've had a hard time finding appropriate tutorials for this so I'm not entirely sure what I'm doing
THanks again
Can you update your sample to include the code for the static resource testerDataSet?
One way you can try and work around this problem is to set the Binding directly in imperative code.
DataGridControl1.DataContext = testerDataSet.Contact
Then you could modify your WPF code to be the following
<xcdg:DataGridControl
Margin="54,18,4,3"
Name="DataGridControl1"
ItemsSource="{Binding}" />
That may not be 100% what you're looking for but it should at least temporarily unblock you.

Resources