XAML ListView Items IsEnabled - wpf

I have the following XAML :
<Grid Grid.Row="3" Margin="8,8">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!-- Setting 'UsingItems' here -->
<CheckBox Grid.Row="0"
IsChecked="{Binding Path=UsingItems}"
Content="{Binding Path=IncludeItemsText}" />
<!-- This works as expected -->
<CheckBox Grid.Row="1"
IsEnabled="{Binding Path=UsingItems}"/>
<!-- This doesn't! Even though the ListView becomes enabled the Items aren't and the Checkboxes are not checkable! -->
<ListView Grid.Row="2" IsEnabled="{Binding Path=UsingItems}"
VerticalAlignment="Stretch"
ItemsSource="{Binding Path=SortedItems}">
<ListView.ItemTemplate>
<DataTemplate>
<DockPanel>
<CheckBox
IsChecked="{Binding Path=.IsSelected}"
Margin="0,2" Click="CheckBox_Click" />
<TextBlock
Text="{Binding Path=.Item.ItemDescription}"
Margin="4,0,0,0"
VerticalAlignment="Top">
</TextBlock>
</DockPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
I would like to Disable all Items in the ListView if the property 'UsingItems' = false. 'UsingItems' is set using the Checkbox in Row 0, I've confirmed this is working by having a dummy Checkbox in Row 1 - the 'IsEnabled' property is set as expected.
However, the ListView Items remain disabled when 'UsingItems' = true, even though the ListView becomes enabled (and the items 'look' enabled).
I had assumed the IsEnabled property would filter down the tree - but this is not happening here.
Where am I going wrong?
Thanks
Joe

Related

WPF - Set initial size of DataGrid within ItemsControl

I Have multiple DataTable's shown via DataGrid:
<ScrollViewer VerticalScrollBarVisibility="Visible">
<ItemsControl ItemsSource="{Binding Path = Data}" ScrollViewer.VerticalScrollBarVisibility="Visible">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Height="auto" >
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<DataGrid Height="auto" VerticalAlignment="Stretch" HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Visible" ItemsSource="{Binding}">
</DataGrid>
<GridSplitter Grid.Row="0" Height="5" HorizontalAlignment="Stretch" VerticalAlignment="Bottom" />
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
Is there an option to limit the initial size to parent's height, or a part of him (for example 50%), and make it resizable (height) by user ?
You are binding Data property to your ItemsControl. The same can go to the Height. Create public property and bind it to Height in view.
<RowDefinition Height="{Binding MyHeightProperty}" />

Display items in dropdown list and selected items box via the same binding using only XAML

I'm sure that someone will jump all over this as being answered somewhere else but I claim I have followed every relevant link on this site (and elsewhere) and tried all possible combinations of ItemTemplate, ComboBoxItem, ItemContainerStyle, DisplayMemberPath, SelectedItem, SelectedValuePath and SelectedValue and for the life of me I can't get this to work as desired.
I simply want to define a list of ContentControl object (using x:Array) in XAML resources used as an ItemsSource for a ComboBox. This list contains 2 elements whose Content property is set to a Grid control - also defined in the resources. Each item also has the Tag property set to a string that functions as the name or description of the content.
Very simply: I want the string in the Tag property to be displayed in the selected item portion of the ComboBox and as the list of selectable items in the dropdown portion of the ComboBox.
If I set DisplayMemberPath="Tag", then the dropdown portion works as desired but nothing is displayed in the selected item portion of the ComboBox. I'm sure that proper use of SelectedValuePath and SelectedValue is the key, but I simply can't get it to work.
<UserControl.Resources>
<Grid x:Key="Fluidics" >
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" MinWidth="134"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Label Content="Cartridge:"
VerticalAlignment="Center" HorizontalAlignment="Left"
Margin="0,5,0,0" Height="26" Width="62"/>
<ComboBox Grid.Column="1"
ItemsSource="{Binding Cartridges}"
SelectedIndex="{Binding SelectedCartridgeIndex, FallbackValue=0}"
SelectedItem="{Binding SelectedCartridge}"
Margin="0,5,0,0" >
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Config.FriendlyName}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<views:FluidicsExperimentParamsView Grid.Row="1" Grid.ColumnSpan="2" DataContext="{Binding FluidicsExperimentParams}" Margin="0,10,0,0"/>
</Grid>
<Grid x:Key="Data acquisition" >
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" MinWidth="157"/>
<ColumnDefinition Width="Auto" MinWidth="87"/>
</Grid.ColumnDefinitions>
<Label Content="Camera line:" />
<ComboBox
Grid.Column="1"
IsReadOnly="True"
ItemsSource="{Binding ImageDataAcquisitionParams}"
SelectedIndex="{Binding SelectedCameraLine}"
SelectedItem="{Binding SelectedImageDataAcquisitionParams}"/>
<data:ImageDataAcquisitionView
Grid.Row="1"
Grid.ColumnSpan="2"
DataContext="{Binding ImageDataAcquisition}" Margin="0,10,0,0"/>
</Grid>
<x:Array x:Key="ControlActivities" Type="ContentControl">
<ContentControl Content="{Binding Source={StaticResource Fluidics}}" Tag="Fluidics" />
<ContentControl Content="{Binding Source={StaticResource Data acquisition}}" Tag="Data acquisition"/>
</x:Array>
</UserControl.Resources>
...
<ComboBox Name="ControlActivityComboBox"
MinWidth="150"
ItemsSource="{Binding Source={StaticResource ControlActivities}}"
SelectedItem="{Binding SelectedActivity}"
SelectedValuePath="Tag"
SelectedValue="{Binding SelectedActivity.Tag}"
DisplayMemberPath="Tag"
HorizontalAlignment="Left"
SelectedIndex="0">
</ComboBox>

How can I bind a listbox selecteditem content to a textbox?

I have a listbox thats getting binded by this query when TextName content changes:
var players =
from p in context.Player
where p.GivenName.StartsWith(TextName.Text.Trim())
select p;
listNames.ItemsSource = players.ToList();
It shows the players names that starts with the text on the textbox. Now when I click any Item (name) from the listbox I need that the TextName shows the player name that's selected on the listbox. I tried to bind it this way:
<TextBox ... Text="{Binding Source=listNames, Path=SelectedItem.Content}" ... />
But when I click a ListboxItem, the textbox just get cleared and does not show anything.. may I have to set up the textbox like I do with the listbox when setting the DisplayMemeberPath???? I need a only one way binding!!
What can I do??
You have 2 problems with your binding:
You are using the Source property instead of the ElementName to specify the list box name
You are trying to bind to a Content property which (I am assuming) does not exist on your Player object. This happens because the SelectedItem property of the ListBox is an instance of Player when you specify an ItemsSource as you have
To solve this you should change your binding to the following:
<TextBox ... Text="{Binding ElementName=listNames, Path=SelectedItem.GivenName}" ... />
<TextBox ... Text="{Binding ElementName=listNames, Path=SelectedItem.Name}" ... />
This binds the TextBox.Text to the ListBoxes - called listNames - SelectedItem, which contains Player objects, and you need its Name property.
<Page
x:Class="Studentt1.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Studentt1"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="Wheat">
<ListBox x:Name="listBox1" ItemsSource="{Binding StudentsList}"
SelectedItem="Binding SelectedStud,Mode=TwoWay}"
DisplayMemberPath="StudName"
HorizontalAlignment="Left" Height="332" Margin="59,173,0,0" VerticalAlignment="Top"
<Button Content="Load" Command="{Binding LoadCommand}" HorizontalAlignment="Left"
Margin="144,567,0,0" VerticalAlignment="Top"/>
<Grid Background="Brown" HorizontalAlignment="Left" Height="352"
VerticalAlignment="Top" Width="633">
<Grid.RowDefinitions>
<RowDefinition Height="50"/>
<RowDefinition Height="50"/>
<RowDefinition Height="50"/>
<RowDefinition Height="50"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="347"/>
<ColumnDefinition Width="401"/>
<ColumnDefinition Width="367*"/>
<ColumnDefinition Width="251*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" FontSize="30" Grid.Column="0" Text="Registration
Number" HorizontalAlignment="Center" Margin="46,0,25,0" Width="276"/>
<TextBox Grid.Row="0" Grid.Column="1" Text="{Binding
ElementName=listBox1,Path=SelectedItem.RegNo,Mode=TwoWay}"/>
<TextBlock Grid.Row="1" Grid.Column="0" FontSize="30" Text="Name"
HorizontalAlignment="Center" Margin="144,0,124,0" Width="79"/>
<TextBox Grid.Row="1" Grid.Column="1" Text="{Binding
ElementName=listBox1,Path=SelectedItem.StudName,Mode=TwoWay}"/>
<TextBlock Grid.Row="2" Grid.Column="0" FontSize="30" Text="Age"
HorizontalAlignment="Center" Margin="157,0,137,0" Width="53"/>
<TextBox Grid.Row="2" Grid.Column="1" Text="{Binding
ElementName=listBox1,Path=SelectedItem.Age,Mode=TwoWay}"/>
</Grid>
</Grid>
</Page>
here i bind the selected item of list box to text box..
you can find zip file for full source code
You should use RelativeSource to access the ListBox, e.g.:
<TextBox ... Text="{Binding RelativeSource={RelativeSource
AncestorType={x:Type ListBox}}, Path=SelectedItem.Content}" .... />

Bind the Height of the Listbox inside the StackPanel to StackPanel`s height

I want to bind the Height of the ListBox to the Height of the StackPanel so the ListBox stretches itself Vertically so the green area is not visible anymore.
When there is no item in the listbox its hidden.
When there is item > 1 the ListBox must be stretching itself to the add/del buttons so the add/del buttons are always at the bottom of the stackpanel(dont want to use dockpanel for that)
How can I do that? I get no binding erros?
<StackPanel x:Name="stack" Background="Green" DataContext="{Binding DocumentViewModelList/}" Orientation="Vertical" >
<ListBox SelectionMode="Single" VirtualizingStackPanel.IsVirtualizing="False"
SelectedItem="{Binding SelectedDocumentViewModel,Mode=TwoWay}"
Height="{Binding ElementName=stack,Path=Height}"
Width="Auto"
Focusable="True"
ScrollViewer.HorizontalScrollBarVisibility="Auto"
ScrollViewer.VerticalScrollBarVisibility="Auto"
Grid.Row="1"
Name="documentListBox"
BorderThickness="1"
ItemsSource="{Binding DocumentList}"
Visibility="{Binding ElementName=documentListBox,Path=HasItems, Converter={StaticResource boolToVisibilityConverter}}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=Id}" />
<TextBlock Text="{Binding Path=Name}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
<!--<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="IsSelected" Value="{Binding Mode=TwoWay, Path=IsSelected}" />
</Style>
</ListBox.ItemContainerStyle>-->
</ListBox>
</StackPanel>
Simply use a Grid instead of a StackPanel:
<Grid x:Name="grid"
Background="Green"
DataContext="{Binding DocumentViewModelList}">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ListBox Grid.Row="0"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch" ..... />
<UniformGrid Grid.Row="1"
Rows="1"
HorizontalAlignment="Center"
VerticalAlignment="Bottom">
<Button Content="Delete" />
<Button Content="Add" />
<Button Content="Open" />
</UniformGrid>
</Grid>
The ListBox simply takes up the entire space of the first row, while the UniformGrid takes up the bottom row with only the space it needs (and makes the buttons all the same size as a bonus).
No need for hard-coded width/height values (or any bindings for height/width), and no value converters needed.
To implement the selective height (if has items x else y) use a value converter... also, I think height will be NaN so try ActualHeight (Bad practice but might work)... use a tool like snoop to see the values!
Is their a specific reason you are using a stackpanel? I grid will work better (StackPanel only give the min space needed where a grid can give as much space as needed)?
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ListBox Grid.Row="1" />
<StackPanel Orientation="Horizontal" Grid.Row="1">
<!-- Buttons -->
</StackPanel>
</Grid>

How do I allow multiple items/content for a user control in WPF?

I've managed to get as far as redirecting content to my stackpanel as shown:
<UserControl
x:Name="taskItem">
<UserControl.ContentTemplate>
<DataTemplate>
<StackPanel>
<Label x:Name="labelHeader" Content="{Binding ElementName=taskItem,Path=Header}" FontFamily="Tahoma" FontSize="16" FontWeight="Bold" />
<Border BorderThickness="0,1,0,0" BorderBrush="#999999" Margin="5,0,5,0">
<StackPanel Margin="10,5,0,0">
<ContentPresenter Content="{TemplateBinding Content}" />
</StackPanel>
</Border>
</StackPanel>
</DataTemplate>
</UserControl.ContentTemplate>
I'm trying to create a control that has a header, a line under it, and then N number of child contents. However, in it's current implementation it won't allow more than one.
What am I doing wrong here?
A user control by definition has one child since it inherits from ContentControl. Make the user control have all the headers and then make ItemsControl the content of the UserControl. Apply your DataTemplate to the ItemTemplate property of the ItemsControl.
<UserControl x:Class="WindowsApplication1.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid Name="MainHeadersGrid" Grid.Row="0">
<TextBlock Text="Put your headers here" />
</Grid>
<ItemsControl Name="childItemsWillGoInHere" ItemsSource="{Binding}" Grid.Row="1">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding PropertyOfItem}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</UserControl>
Now, assign the UserControl's template's DataContext to a collection of the objects you want to display.

Resources