WPF XAML ComboBox Width - wpf

I have the following xaml with all the binding removed;
<StackPanel Grid.Row="2" Grid.Column="1" Orientation="Horizontal" HorizontalAlignment="Left" Height="20">
<ComboBox x:Name="ddlDay" Width="30"/>
If I set the width of the combobox to 200 it works but if I set it to 50 it doesn't size past the default.
I'm kinda new to xaml so is this default behavior or what do I do to make the combobox small?

I'm not able to reproduce the behavior you are describing. I tried it with the following test:
<Window x:Class="ComboWidthSample.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>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left" Height="20">
<ComboBox ItemsSource="{Binding}" Width="30" />
<ComboBox ItemsSource="{Binding}" Width="50" />
<ComboBox ItemsSource="{Binding}" Width="200" />
</StackPanel>
</Grid>
</Window>
using System.Linq;
namespace ComboWidthSample
{
public partial class Window1
{
public Window1()
{
InitializeComponent();
DataContext = Enumerable.Range(1, 10).Select(i => "My ComboBox Item " + i).ToList();
}
}
}
Are you doing something different than that? Perhaps databinding to the Width property or styling your ComboBox?

Related

Listview DataTemplate inter UserControl unable to binding

I have this problem:
I have a ListView control in the form. There is a CustomControl in the DataTemplate of this ListView. I want this custom control to be bound to the Time property in the ViewModel of the current form, but it cannot be bound, but the DataTemplate Other controls in the middle can be bound, what is going on? I will be very grateful
Here is my window:
<ListView Grid.Row="2"
ItemsSource="{Binding PlanRotation}">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Margin="20 0 0 0" Orientation="Horizontal">
<TextBlock HorizontalAlignment="Center" Text="时间:" VerticalAlignment="Center" FontWeight="Bold" />
<TimeControl:DateTimePicker Tag="{Binding ElementName=myWin,Path=DataContext.Time,Mode=OneWayToSource}"
HorizontalAlignment="Center"
Height="28"
VerticalAlignment="Center"
Width="152"
Foreground="White"
BorderThickness="1"
BorderBrush="#FFABADB3"
Background="Black"
Grid.Column="1"/>
<ComboBox Text="{Binding ElementName=myWin,Path=DataContext.Scenes,Mode=OneWayToSource}"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Width="80"
Height="21">
</ComboBox>
Here is my CustomControl TimeControl:DateTimePicker code:
<UserControl x:Class="ManagementProject.UserControls.TimeControl.DateTimePicker"
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:ManagementProject.UserControls.TimeControl"
xmlns:myTime="clr-namespace:ManagementProject.UserControls.TimeControl"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
mc:Ignorable="d"
d:DesignHeight="25"
d:DesignWidth="150"
Width="150"
MaxHeight="25"
x:Name="dtpName"
Loaded="UserControl_Loaded" Tag="{Binding ElementName=textBlock1, Path=Text}">
<TextBox
Height="23"
HorizontalAlignment="Left"
Text="{Binding ElementName=dtpName,Path=Tag,Mode=OneWayToSource,UpdateSourceTrigger=PropertyChanged}"
Margin="4,3,0,0"
Name="textBlock1"
VerticalAlignment="Top"
Width="123" Foreground="White" Background="{x:Null}" BorderBrush="{x:Null}" SelectionBrush="{x:Null}" Style="{DynamicResource TextBoxStyle1}" />
My Custom control's TextBox's Text is assignment in the background.
I could only get straight up binding to work with a user control when it initialized. I ended up created a dependency property to be able to update the user control from outside it.
internal List<User> ContactlistContainer
{
get => (List<User>)GetValue(ContactlistContainerProperty);
set => SetValue(ContactlistContainerProperty, value);
}
internal static readonly DependencyProperty ContactlistContainerProperty =
DependencyProperty.Register("ContactlistContainerProperty", typeof(List<User>), typeof(User), new PropertyMetadata(new List<User>()));

Why does the ExtentWidth stay at 10.003?

So I have a ListBox that has a DataTemplate which has a Grid which has a RichTextBox.
For some reason when you type into the RichTextBox it puts each character on a separate line. Digging into this, I find out that the ExtentWidth is equal to 10.003. Why? I have no idea. I was hoping someone could explain to me why and give a nice solution to make it stop doing this.
I did notice that if you set a width on the grid's column, it fixes it, but I don't want a static width on my grid's column.
Below is an example of the problem. I am using .Net 4 and VS 2010.
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication1"
Title="MainWindow" Height="350" Width="525">
<ListBox
DockPanel.Dock="Top"
x:Name="TestListBox">
<ListBox.ItemTemplate>
<DataTemplate DataType="{x:Type local:Test}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<TextBox Grid.Column="0" Grid.Row="0" Text="{Binding Name}" />
<TextBlock Grid.Column="1" Grid.Row="0" Text="Test" />
<RichTextBox
Grid.Column="1" Grid.Row="1"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
<local:Test Name="Test1" />
<local:Test Name="Test2" />
</ListBox>
using System.Windows;
namespace WpfApplication1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
}
public class Test
{
public string Name { get; set; }
public Test()
{
}
}
}
So I figured out a workaround. If you trade out the ListBox for a DataGrid and use DataGridTemplateColumns with the Width of the TemplateColumn set to "*" then it seems to work.
<DataGrid
x:Name="TestDataGrid"
CanUserReorderColumns="False"
CanUserResizeColumns="False"
>
<DataGrid.Columns >
<DataGridTemplateColumn Width="*">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<RichTextBox />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
<local:Test Name="Test1" />
<local:Test Name="Test2" />
</DataGrid>
Note I also set the CanUserResizeColumns to False because if you don't and they resize them, the ExtentWidth will snap back to 10.

Removing left and right border sides from listbox datatemplate

Currently I have specified borders for all datatemplated items in my horizontal listbox which is fine because I DO want borders for all individual listboxitems, but I would like to remove the left border from the first item and the right border from the last item. Is this even possible?
Xaml:
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical" Background="DimGray">
<Border BorderBrush="White" BorderThickness="1">
<Canvas Height="80" Width="140">
<TextBlock Text="{Binding Name}" TextAlignment="Center" Canvas.Top="22" Height="80" Width="140" FontSize="26"></TextBlock>
</Canvas>
</Border>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
Thanks
It is, with a DataTemplateSelector, you just need to implement the logic to select the correct DataTemplate, here's a fulle example with your code. You should be able to just copy / paste the following code in your project. There are comments in there that explain what's going on. Hope it helps!
XAML:
<Window x:Class="StackOverflowTests.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:local="clr-namespace:StackOverflowTests"
Title="Window1"
x:Name="window1"
Width="800"
Height="600">
<Window.Resources>
<!-- Instantiate the DataTemplateSelector -->
<local:ItemDataTemplateSelector x:Key="ItemDataTemplateSelector" />
</Window.Resources>
<!-- Assign the DataTemplateSelector to the ListBox's ItemTemplateSelector -->
<ListBox Margin="8" ItemsSource="{Binding}" ItemTemplateSelector="{StaticResource ItemDataTemplateSelector}">
<ListBox.Resources>
<!-- Template without Left border -->
<DataTemplate x:Key="firstItemTemplate">
<StackPanel Orientation="Vertical" Background="DimGray">
<Border BorderBrush="Red" BorderThickness="0,1,1,1">
<Canvas Height="80" Width="140">
<TextBlock Text="{Binding Name}" TextAlignment="Center" Canvas.Top="22" Height="80" Width="140" FontSize="26"></TextBlock>
</Canvas>
</Border>
</StackPanel>
</DataTemplate>
<!-- Template with all borders -->
<DataTemplate x:Key="regularItemTemplate">
<StackPanel Orientation="Vertical" Background="DimGray">
<Border BorderBrush="Red" BorderThickness="1,1,1,1">
<Canvas Height="80" Width="140">
<TextBlock Text="{Binding Name}" TextAlignment="Center" Canvas.Top="22" Height="80" Width="140" FontSize="26"></TextBlock>
</Canvas>
</Border>
</StackPanel>
</DataTemplate>
<!-- Template without the Right border -->
<DataTemplate x:Key="lastItemTemplate">
<StackPanel Orientation="Vertical" Background="DimGray">
<Border BorderBrush="Red" BorderThickness="1,1,0,1">
<Canvas Height="80" Width="140">
<TextBlock Text="{Binding Name}" TextAlignment="Center" Canvas.Top="22" Height="80" Width="140" FontSize="26"></TextBlock>
</Canvas>
</Border>
</StackPanel>
</DataTemplate>
</ListBox.Resources>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
</Window>
C#:
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
namespace StackOverflowTests
{
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
this.DataContext = new List<Person>()
{
new Person() { Name = "Jim Morrison" },
new Person() { Name = "Ozzy Osbourne" },
new Person() { Name = "Slash" },
new Person() { Name = "Jimmy Page" }
};
}
}
public class Person
{
public string Name { get; set; }
}
public class ItemDataTemplateSelector : DataTemplateSelector
{
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
FrameworkElement element = container as FrameworkElement;
// get the ListBoxItem
ListBoxItem listBoxItem = element.TemplatedParent as ListBoxItem;
// get the ListBoxItem's owner ListBox
ListBox listBox = ItemsControl.ItemsControlFromItemContainer(listBoxItem) as ListBox;
// get the index of the item in the ListBox
int index = listBox.Items.IndexOf(item);
// based on the index select the template
if (index == 0)
return element.FindResource("firstItemTemplate") as DataTemplate;
else if (index == listBox.Items.Count - 1)
return element.FindResource("lastItemTemplate") as DataTemplate;
else
return element.FindResource("regularItemTemplate") as DataTemplate;
}
}
}

Silverlight Data Binding for Collection in Stack Panel

I'm new to Silverlight, so I don't have a complete grasp of all the controls at my disposal. What I would like to do is use databinding and a view model to maintain a collection of items. Here is some mock code for what I'd like to do:
Model
public class MyItem
{
public string DisplayText { get; set; }
public bool Enabled { get; set; }
}
ViewModel
public class MyViewModel : INotifyPropertyChanged
{
private ObservableCollection<MyItem> _myItems = new ObservableCollection<MyItem>();
public ObservableCollection<MyItem> MyItems
{
get { return _myItems; }
set
{
_myItems = value
NotifyPropertyChanged(this, "MyItems");
}
}
}
View
<Grid x:Name="LayoutRoot" Background="White">
<StackPanel ItemsSource="{Binding MyItems}">
<StackPanel Orientation="Horizontal">
<CheckBox "{Binding Enabled, Mode=TwoWay}"></CheckBox>
<TextBlock Text="{Binding DisplayText, Mode=TwoWay}" />
</StackPanel>
</StackPanel>
</Grid>
So my end goal would be that every time I add another MyItem to the MyItems collection it would create a new StackPanel with checkbox and textblock. I don't have to use a stack panel but just thought I'd use that for this sample.
Looks like you want a <ListBox>, then set the <ListBox.ItemTemplate> to your <StackPanel> something like this.....
<ListBox ItemsSource=”{Binding Classes, Source={StaticResource model}}”>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox "{Binding Enabled, Mode=TwoWay}"/>
<TextBlock Text="{Binding DisplayText, Mode=TwoWay}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
here is a great example (it's WPF, but should only be minor changes for silverlight)
yes, looks like you want a <ListBox>
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SilverlightApplication4.MainPage"
Width="640" Height="480">
<UserControl.Resources>
<DataTemplate x:Key="ItemTemplate">
<StackPanel Orientation="Horizontal">
<CheckBox IsChecked="{Binding Enabled, Mode=TwoWay}"/>
<TextBlock Text="{Binding DisplayText}"/>
</StackPanel>
</DataTemplate>
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="White" DataContext="{Binding Source={StaticResource SampleDataSource}}">
<ListBox Margin="0,0,8,0" ItemTemplate="{StaticResource ItemTemplate}" ItemsSource="{Binding Collection}"/>
</Grid>
This code will give you a ListBox with all your Data bound to a Checkbox and TextBlock with the Checkbox first and TextBox next to it.

WPF: how to get remaining width in a StackPanel?

Given the code below:
<Window x:Class="Window3"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window3" Height="300" Width="300">
<StackPanel Background="Yellow" Orientation="Horizontal">
<TextBlock Background="Green" Text="some text" Width="200"/>
<TextBox Width="{Binding ???}" />
<TextBlock Background="Red" Text="some text" Width="50"/>
</StackPanel>
</Window>
how do you bind second textbox's width as to fill the remaining space?
Please keep in mind I'm looking for a binding solution: I know how to do it using other layouts (like DockPanel or grid) but I'm not interested in that. Also, using ElementName is not of interest.
Thanks.

Resources