#c# #wpf #listbox #grid #stackpanel
#c# #wpf #список #сетка #stackpanel
Вопрос:
Это может быть глупый вопрос, но я застрял, делая это :(. У меня есть сетка и 3 столбца. У меня есть текстовое поле и список в каждом из этих 3 столбцов, как показано:
<Grid.ColumnDefinitions>
<ColumnDefinition Width="130"></ColumnDefinition>
<ColumnDefinition Width="380"></ColumnDefinition>
<ColumnDefinition Width="146"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="30"></RowDefinition>
</Grid.RowDefinitions>
<StackPanel Grid.Column="0" Grid.Row="0">
<TextBox Text="File Name" Height="30"></TextBox>
</StackPanel>
<StackPanel Grid.Column="1" Grid.Row="0">
<TextBox Text="File Path" Height="30"></TextBox>
</StackPanel>
<StackPanel Grid.Column="2" Grid.Row="0">
<TextBox Text="File Size" Height="30"></TextBox>
</StackPanel>
<StackPanel Grid.Column="0">
<ListBox Name="listbox_name" Margin="1,30" Height="276" />
</StackPanel>
<StackPanel Grid.Column="1">
<ListBox Name="listbox_path" Margin="1,30" Height="276" />
</StackPanel>
<StackPanel Grid.Column="2">
<ListBox Name="listbox_size" Margin="1,30" Height="276" />
</StackPanel>
и код, стоящий за ним:
public Window1()
{
InitializeComponent();
list.Add("D:\a\hy");
list.Add("D:\a\hy1");
list.Sort();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
listbox_name.ItemsSource = list;
grid1.Visibility = Visibility.Hidden;
}
private void button1_Click(object sender, RoutedEventArgs e)
{
grid1.Visibility = Visibility.Visible;
}
Но при нажатии кнопки я не могу видеть списки с отображаемым списком. Пожалуйста, подскажите мне, где я ошибаюсь. Спасибо!
Комментарии:
1. почему вы используете так много панелей стека для отображения заголовков… Просто используйте ListView и используйте GridView внутри него и создайте столбцы GridView….
2. привет,@adcool2007 я новичок, поэтому не знаю, как поступить. попробую и ваш метод, спасибо!
Ответ №1:
Причина в том, что ваш stackPanel
находится в Grid.Col="0"
, и он очень маленький. Но ListBox
находится внутри вашего stackPanel
. У него есть запас, и он уменьшается. Вы не можете видеть свой listBox
.
Если вы сделаете что-то подобное:
<StackPanel Margin="0,0,0,-279">
<ListBox Name="listbox_name" Margin="1,30" Height="276" />
</StackPanel>
вы увидите свой список, и он будет работать.
ПРИМЕЧАНИЕ: этот код является только примером. Вам нужно сделать лучший макет для вашего окна.
Вот как я сделал переключение окна:
<Window x:Class="WpfApplication2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="678" Loaded="Window_Loaded">
<Grid Name="grid1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="130"></ColumnDefinition>
<ColumnDefinition Width="380"></ColumnDefinition>
<ColumnDefinition Width="146"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="30"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<TextBlock Text="File Name" Grid.Row="0" Grid.Column="0" Margin="5" />
<TextBlock Text="File Path" Grid.Row="0" Grid.Column="1" Margin="5" />
<TextBlock Text="File Size" Grid.Row="0" Grid.Column="2" Margin="5" />
<ListBox Name="listbox_name" Grid.Row="1" Grid.Column="0" BorderBrush="Black" />
<ListBox Name="listbox_path" Grid.Row="1" Grid.Column="1" BorderBrush="Black" />
<ListBox Name="listbox_size" Grid.Row="1" Grid.Column="2" BorderBrush="Black" />
</Grid>
</Window>
Комментарии:
1. Привет, @sergey: Спасибо, это отлично работает! 🙂 но как насчет двух других? Как я могу их отобразить? Как и во всех 3 вместе?
2. Привет, @sergey: да, это именно то, что мне было нужно, спасибо! 🙂 У меня есть расширитель, как мне сделать сетку видимой (и изменить размер окна в соответствии с сеткой) при расширении расширителя? Огромное спасибо!
3. Но в этом случае пространство сетки отображается, даже если расширитель не расширен. Как мне увеличить размер окна при нажатии на расширитель?
4. Хммм. теперь я задал высоту моего окна = «181» Width =»Auto» SizeToContent=»WidthAndHeight». Моя кнопка и расширитель находятся за пределами grid1. Когда я разворачиваю расширитель, размер окна увеличивается, но сетка отображается поверх кнопки и расширителя. Как я могу этого избежать? Спасибо!
Ответ №2:
<ListView Name="list"
Grid.Row="1"
ItemsSource={Binding Path=Files}
>
<ListView.View>
<GridView>
<GridViewColumn Header="Name">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Button>
<TextBlock Text="{BindingPath=Name}"/>
</Button>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Size">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Button>
<TextBlock Text="{BindingPath=Size}"/>
</Button>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Path">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Button>
<TextBlock Text="{BindingPath=Path}"/>
</Button>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
Моя ваша ViewModel будет
public class FileListViewModel : INotifyPropertyChanged
{
/// <summary>
///
/// </summary>
public ObservableCollection<Fileinfo> Files{ get; set; }
private Fileinfo selectedFile;
public Fileinfo SelectedFile
{
get { return selectedFile; }
set
{
selectedFile= value;
InvokePropertyChanged(new PropertyChangedEventArgs("SelectedFile"));
}
}
public PersonListViewModel()
{
//Loading List
Files= new ObservableCollection<Fileinfo>()
{ //This is temp list you modify accordinh to you logic
new FileInfo{Name = "File32"},
new FileInfo{Name = "File33"},
new FileInfo{Name = "File373"},
new FileInfo{Name = "File393"},
new FileInfo{Name = "File345"},
new FileInfo{Name = "File375"},
new FileInfo{Name = "File395"},
new FileInfo{Name = "File387"},
new FileInfo{Name = "File387"}
};
}
#region Implementation of INotifyPropertyChanged
/// <summary>
///
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
///
/// </summary>
/// <param name="e"></param>
public void InvokePropertyChanged(PropertyChangedEventArgs e)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
handler(this, e);
}
#endregion
}
Ваша модель должна быть похожа
public class FileinFo: INotifyPropertyChanged
{
private string size;
public event PropertyChangedEventHandler PropertyChanged;
private string name;
private bool isSelected;
public string Size
{
get { return size; }
set
{
size= value;
InvokePropertyChanged(new PropertyChangedEventArgs("size"));
}
}
public string Name
{
get { return name; }
set
{
name = value;
InvokePropertyChanged(new PropertyChangedEventArgs("Name"));
}
}
public bool IsSelected
{
get { return isSelected; }
set
{
isSelected = value;
InvokePropertyChanged(new PropertyChangedEventArgs("IsSelected"));
}
}
public void InvokePropertyChanged(PropertyChangedEventArgs e)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, e);
}
}
Вам нужно установить datacontext вашего представления в ViewModel
итак, допустим, ваше представление называется FileListView.xaml
Затем в коде за конструктором вы можете написать
this.DataContext= new FileListViewModel();
Комментарии:
1. Привет, adcool, я знаю, что опаздываю, но я пробую метод, который вы предложили, поскольку мои требования так говорят. Я не уверен, возможно ли это, но есть ли способ в listview, чтобы я мог отобразить в нем arraylist? Нужна ли мне привязка к классу? Спасибо!
2. @user877852 — ваш список массивов содержит объекты того же типа. затем просто используйте ItemsSource= {Путь привязки=ListOfObjects}…. Также, если Объекты одного и того же типа… использовать общий список<>
3. привет @adcool, извини, но я новичок в этом. У меня есть три списка массивов. Я помещаю каждый из них под разные объекты (имя, путь и размер) и связываю их с помощью <ListBox ItemsSource=»{Путь привязки= name}» IsSynchronizedWithCurrentItem=»True»/> Я все еще не получаю правильного ответа. как я могу продолжить? Спасибо!