|
I have two ListBoxes on the screen, and this is my requirement:- Upon loading the window, the first listbox (ListBox1) should be populated with items (which is happening correctly), but I also want the first item to be selected. This is to happen via MVVM, and not through codebehind. And upon selecting in the first listbox (ListBox1), the second listbox (ListBox2) should be populated (which is happening correctly), and its first item (of ListBox2) is to be selected.
How is this listbox selection to be achieved via MVVM?
modified 21-Nov-21 0:50am.
|
|
|
|
|
Your listbox1 needs to handle the SelectionChanged event, which when executed, populates the collection for listbox2. Since listbox2 is bound to the appropriate collection, it will automatically update itself.
You didn't say whether or not you wanted to retain the selected item from listbox1 in the viewmodel.
I'm assuming that your bound collections for both list boxes are ObservableCollection s...
To automatically select the first item in listbox1, simply set the SelectedIndex property to 0.
".45 ACP - because shooting twice is just silly" - JSOP, 2010 ----- You can never have too much ammo - unless you're swimming, or on fire. - JSOP, 2010 ----- When you pry the gun from my cold dead hands, be careful - the barrel will be very hot. - JSOP, 2013
|
|
|
|
|
Ahh ... but you didn't say "where" to set index to 0. He wants "no code behind". I guess you can set it in XAML, but isn't it "0" anyway? (Actually, I thinks it's -1 when newly loaded. Shrug)
Just taking digs at "no code behind" MVVM; not your answer.
It's "plumbing". To say you can't put it in a loaded event (as "code") is OCD, IMO.
It was only in wine that he laid down no limit for himself, but he did not allow himself to be confused by it.
― Confucian Analects: Rules of Confucius about his food
|
|
|
|
|
"No code behind" is a pointless endeavour, and a highly artificial requirement. It also means that he app is virtually impossible (or at least a pain in the ass) to debug. I make it a practice to put as much as possible in the code behind for this very reason. Sure, control interaction can be put into the XAML many times, but I pretty much use code-behind for everything.
In the real world, you do what works, and use the simplest means possible. Doing the work is no time to exercise classroom theory or hypotheticals. Experienced programmers (like us) are cognizant of these facts and are much more efficient coders as a result.
".45 ACP - because shooting twice is just silly" - JSOP, 2010 ----- You can never have too much ammo - unless you're swimming, or on fire. - JSOP, 2010 ----- When you pry the gun from my cold dead hands, be careful - the barrel will be very hot. - JSOP, 2013
|
|
|
|
|
Thanks for your replies.
In fact, I have a fully working Codebehind solution, which is quite less code, and is working perfectly well. I was asked by my manager to convert it to MVVM, and am facing somewhat unsurmountable difficulties, in making it non-codebehind. That was the reason for my question. Now, having listened to the opinion of experts like you, I will convince my manager that some codebehind is not taboo.
|
|
|
|
|
To be clear, MVVM does not mean no code-behind. It’s about separation of concerns. The model loads and saves the data. The view model both transforms the model for, and eases interaction with the view. The view binds the view model to the ui. MVVM can be implemented in such a way as to couple the three concerns as loosely or as tightly as is necessary.
".45 ACP - because shooting twice is just silly" - JSOP, 2010 ----- You can never have too much ammo - unless you're swimming, or on fire. - JSOP, 2010 ----- When you pry the gun from my cold dead hands, be careful - the barrel will be very hot. - JSOP, 2013
|
|
|
|
|
After yesterday's demo, the requirement got changed. Instead of two listboxes, one listbox and one datagrid is what is needed. So, I am off to understanding datagrid programming now. The weird software world we are all in
|
|
|
|
|
There's also an inclination to get carried away with "data grids". They're useful for browsing but they'll suck up all your development time if you (try to) use them for data entry instead of using a "form" (for the data entry / update part).
It was only in wine that he laid down no limit for himself, but he did not allow himself to be confused by it.
― Confucian Analects: Rules of Confucius about his food
|
|
|
|
|
I use ListViews. In fact. I wrote an article on CodeProject that illustrates a custom ListView control that can auto-generate columns based on the dataset being represented. It doesn't support editable cells, but it does have sort functionality (that can be toggled on a column-by-column basis, column name overrides, custom column formatting, and other stuff.
Auto-generated columns in a WPF ListView[^]
".45 ACP - because shooting twice is just silly" - JSOP, 2010 ----- You can never have too much ammo - unless you're swimming, or on fire. - JSOP, 2010 ----- When you pry the gun from my cold dead hands, be careful - the barrel will be very hot. - JSOP, 2013
|
|
|
|
|
Hi,
I want to create a digital clock at the top right of my application. I wrote backend codes for the clock and the clock works fine. But, I want to use custom digital font for the clock. I downloaded the font from DS-Digital Font | dafont.com[^] and added them to the fonts folder in my project. I used Resource as build action and selected Do not copy. The App.xaml is as follow:
<FontFamily x:Key="Digital">pack:
and MainWindow.xaml:
<Label Name="TimeLabel" Grid.Column="1" Foreground="White" FontSize="24" FontFamily="{StaticResource Digital}">00:00:00</Label>
The problem is that the font is not applied to the label.
Please help me.
Thanks.
|
|
|
|
|
Try this:
<Window.Resources>
<Style x:Key="Digital" x:Type="Label">
<Setter Property="TextElement.FontFamily" Value="Fonts/#DS-DIGI" />
</Style>
</Window.Resources>
And then set the style of the control to that style.
<Label Name="TimeLabel" Grid.Column="1" Foreground="White" FontSize="24" Style={StaticResource Digital}">00:00:00</Label>
".45 ACP - because shooting twice is just silly" - JSOP, 2010 ----- You can never have too much ammo - unless you're swimming, or on fire. - JSOP, 2010 ----- When you pry the gun from my cold dead hands, be careful - the barrel will be very hot. - JSOP, 2013
|
|
|
|
|
I'm getting error: the attribute 'Type' from the XAML namespace is not Defined in the first code block you gave. How can I resolve it?
|
|
|
|
|
Change it to TargetType="Label" .
This is what I get for giving a code example without typing it out in the IDE first.
".45 ACP - because shooting twice is just silly" - JSOP, 2010 ----- You can never have too much ammo - unless you're swimming, or on fire. - JSOP, 2010 ----- When you pry the gun from my cold dead hands, be careful - the barrel will be very hot. - JSOP, 2013
|
|
|
|
|
This method cannot change the font. I think there is something with fonts. Some fonts cannot be used in WPF.
|
|
|
|
|
Try this one:
Font Empire - Digital Readout[^]
".45 ACP - because shooting twice is just silly" - JSOP, 2010 ----- You can never have too much ammo - unless you're swimming, or on fire. - JSOP, 2010 ----- When you pry the gun from my cold dead hands, be careful - the barrel will be very hot. - JSOP, 2013
|
|
|
|
|
DS-Digital works fine in WPF. I'm using it in a tool I wrote last year.
I added the font .ttf files to a Fonts folder in my project. Set them to "Resource", NOT "Embedded Resource".
In my XAML, I've got the following:
<Window.Resources>
<FontFamily x:Key="ValueFont">./Fonts/#DS-Digital</FontFamily>
...
</Window.Resources>
...and wherever I want to use the font:
<TextBlock ... FontFamily="{StaticResource ValueFont}" ... </TextBlock>
Of course, you can always use the same font path in a Style block with a FontFamily.
modified 15-Nov-21 9:21am.
|
|
|
|
|
I have a set of five buttons, in a StackPanel, which is a user control. I would like to use this same StackPanel in two different places on the screen, with different orientations - Horizontal in one place, and Vertical in the other place. Is it possible to do it in WPF?
(I can have two different user controls, but most of the code will be same between the two, the only difference being in their orientations. I would like to reuse the StackPanel in both these places, with different orientations).
Thanks in advance.
|
|
|
|
|
Use the .Tag property of the user control (UC) to pass the orientation ("H" or "V") to the UC's Loaded event.
Then set the orientation of the stack panel based on the value of .Tag in the UC's Loaded event.
string tag = this.Tag as string;
xxx.Orientation = (tag == "H") ? Orientation.Horizontal : Orientation.Vertical;
It was only in wine that he laid down no limit for himself, but he did not allow himself to be confused by it.
― Confucian Analects: Rules of Confucius about his food
|
|
|
|
|
Thank you very much. Will try this out in my code.
|
|
|
|
|
You're welcome!
It was only in wine that he laid down no limit for himself, but he did not allow himself to be confused by it.
― Confucian Analects: Rules of Confucius about his food
|
|
|
|
|
I am new to VB.net and WPF.
and i need some help.
When i select a item in the combobox.
then i will have that Directory i have selected in the combobox. add to the listbox or treeview (as a treeview with folders/subfolders/... and files)
edit:
My problem is i apparently can't use .Nodes in my VB.net code.
And my events (afterselected) is useless..
I can use it in VB.net(winforms) but not as WPF (Class Library)
Imports System.Windows
Imports System.Windows.Controls
Imports System.Windows.Data
Imports System.Windows.Input
Public Class VerticalPaneExample
Dim root = "c:\temp\"
Dim matroot As String = ""
Dim newtoolsti As String = ""
Dim enodetext As String = ""
Private Sub VerticalPaneExample_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
Dim folders() As String = IO.Directory.GetDirectories(root)
For Each folder As String In folders
Dim clean As String
clean = folder.Replace(root, "")
Me.matpicker.Items.Add(clean)
Next
End Sub
Private Sub matpicker_AfterSelect(sender As Object, e As RoutedEventArgs) Handles matpicker.AfterSelect
Me.matpicker.SelectedItem = matroot
For Each direct As String In System.IO.Directory.GetDirectories(matroot)
Dim dir As String = System.IO.Path.GetFileNameWithoutExtension(direct)
Dim newNode = viewptffiles.Nodes.Add(dir, dir)
RecurseChildFolders(direct, newNode)
Try
For Each file As String In System.IO.Directory.GetFiles(direct, "*.*")
newNode.Nodes.Add(System.IO.Path.GetFileName(file))
Next
Catch ex As Exception
End Try
Next
Private Sub RecurseChildFolders(directory As String, parent As TreeNode)
For Each direct As String In System.IO.Directory.GetDirectories(directory)
Dim dir As String = System.IO.Path.GetFileNameWithoutExtension(direct)
Dim child = parent.Nodes.Add(dir, dir)
RecurseChildFolders(direct, child)
Try
For Each file As String In System.IO.Directory.GetFiles(direct, "*.*")
child.Nodes.Add(System.IO.Path.GetFileName(file))
Next
Catch ex As Exception
End Try
Next
End Sub
End Class
My xaml file look like this:
<pre><UserControl x:Class="VerticalPaneExample"
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"
xmlns:local="clr-namespace:ExamplePowerMillPluginVB"
mc:Ignorable="d"
d:DesignHeight="1000"
d:DesignWidth="450"
Background="White">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="10"/>
<ColumnDefinition Width="380"/>
<ColumnDefinition Width="10"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="10"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="10"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="10"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<ComboBox
x:Name="matpicker"
Grid.Row="1"
Grid.Column="1"
Height="20"
Width="380"
SelectedIndex="-1"
></ComboBox>
<ListBox
x:Name="viewptffiles"
Grid.Row="3"
Grid.Column="1"
Height="500"
Width="380"
/>
<Button
x:Name="Importt"
Content="Import Tool"
Grid.Row="5"
Grid.Column="1"
Height="40"
/>
</Grid>
</UserControl>
modified 1-Nov-21 6:39am.
|
|
|
|
|
You've told us what you want to do, and shown your code, but you forgot to tell us what the problem is or where you're stuck.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Sorry..
My problem is i apparently can't use .Nodes in my VB.net code.
And my events (afterselected) is useless..
I can use it in VB.net(winforms) but not as WPF (Class Library)
|
|
|
|
|
|
I'm creating a WPF DataGrid. The data source is a DataTable created in the VM. See this pic.
I'm creating a DataTable in the VM, then binding the DataGrid to it. That part all works fine. I now want to apply a cell style:
View Model
string[] columnNames = (from dc in BudgetTable.Columns.Cast<DataColumn>()
select dc.ColumnName).ToArray();
foreach (string item in columnNames)
{
Binding binding = new Binding(item);
string styleName = "";
if (item == "Type")
{
binding.Mode = BindingMode.OneTime;
styleName = "budgetGridCellStyle";
}
else
{
binding.Mode = BindingMode.TwoWay;
binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
styleName = "dataGridCurrencyCellStyle";
}
var style = Application.Current.FindResource(styleName) as Style;
var col = new DataGridTextColumn()
{
Header = item,
Binding = binding,
Visibility = Visibility.Visible,
CellStyle = style
};
DataGridColumns.Add(col);
}
Style
<Style x:Key="dataGridCurrencyCellStyle"
BasedOn="{StaticResource dataGridCellStyle}"
TargetType="{x:Type DataGridCell}">
<Setter Property="TextBlock.Text" Value="{Binding StringFormat={}{0:0.##}}"/>
<Setter Property="IsEnabled" Value="{Binding AreFieldsEnabled}"/>
</Style>
The setters won't work:
- The string format setting is not being applied no matter what I change it to. What's the right way to do this?
- The IsEnabled causes a BindingExpression error. AreFieldsEnabled is a bool property on the VM. How do I reference that from this style?
Thanks
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
modified 27-Oct-21 16:36pm.
|
|
|
|