Я занят, создавая мое первое приложение MVVM в WPF.
В основном проблема, которую я имею, состоит в том, что у меня есть TreeView (Система. Windows. Средства управления. TreeView), который я поместил на свое Окно WPF, я имею, решают, что я свяжу с ReadOnlyCollection объектов CommandViewModel, и эти объекты состоят из DisplayString, Тега и RelayCommand.
Теперь в XAML, у меня есть свой TreeView, и я успешно связал свой ReadOnlyCollection с этим. Я могу просмотреть это, и все выглядит хорошо в UI.
Проблема теперь - то, что я должен связать RelayCommand с Командой TreeViewItem, однако от того, что я вижу, что TreeViewItem не имеет Команды. Это вынуждает меня сделать это в свойстве IsSelected или даже в Коде позади метода TreeView_SelectedItemChanged или является там способом сделать это волшебно в WPF?
Это - код, который я имею:
<TreeView BorderBrush="{x:Null}"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
<TreeView.Items>
<TreeViewItem
Header="New Commands"
ItemsSource="{Binding Commands}"
DisplayMemberPath="DisplayName"
IsExpanded="True">
</TreeViewItem>
</TreeView.Items>
и идеально я хотел бы просто пойти:
<TreeView BorderBrush="{x:Null}"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
<TreeView.Items>
<TreeViewItem
Header="New Trade"
ItemsSource="{Binding Commands}"
DisplayMemberPath="DisplayName"
IsExpanded="True"
Command="{Binding Path=Command}">
</TreeViewItem>
</TreeView.Items>
Делает у кого-то есть решение, которое позволяет мне использовать инфраструктуру RelayCommand, которую я имею.
Спасибо парни, очень ценившие!
Richard
Самый простой способ сделать это, и его дешевый, это получить бумажную человеческую страницу для cscope и создать текстовый файл... например:
$ man cscope | col -b > cscope.txt
Или, чтобы преобразовать в ps файл для передачи в Ghostscript:
$ man -t cscope > cscope.ps $ gs cscope.ps -sOutputFile=cscope.pdf-121--4460139-
Я согласен, если вы попытаетесь поместить MireItemSeparator
в, он пожалуется, что только MireItem
может быть дочерним, когда GWT пытается создать виджет. Поскольку в настоящее время это не поддерживается, я предлагаю вам запросить это в качестве будущего расширения для команды GWT.
Тем временем можно добавить разделитель программным способом и добавить команду следующим образом: XML-файл:
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder" xmlns:g="urn:import:com.google.gwt.user.client.ui">
<g:HTMLPanel>
<g:MenuBar ui:field="menuBar">
<g:MenuItem ui:field="helpMenuItem">Help</g:MenuItem>
<g:MenuItem ui:field="aboutMenuItem">About</g:MenuItem>
<g:MenuItem ui:field="siteMapMenuItem">Site Map</g:MenuItem>
</g:MenuBar>
</g:HTMLPanel>
Java-файл (ы):
public class Menu extends Composite {
...
@UiField MenuBar menuBar;
@UiField MenuItem helpMenuItem;
...
public Menu() {
initWidget(uiBinder.createAndBindUi(this));
// insert a separator
menuBar.insertSeparator(1);
// attach commands to a menu item
helpMenuItem.setCommand(new MenuCommand(HistoryToken.Help));
...
}
public class MenuCommand implements Command {
final HistoryToken historyToken;
public MenuCommand(HistoryToken historyToken) {
this.historyToken = historyToken;
}
@Override
public void execute() {
historyToken.fire();
}
}
public enum HistoryToken {
Help,About,SiteMap;
public void fire(){
History.newItem(this.toString());
}
}
В другом месте моего кода я реализовал HistiveListener
, чтобы уловить любые изменения, т.е.
class HistoryManager implements ValueChangeHandler<String> {
// 1. get token
// 2. change it into a HistoryToken
// 3. perform switch statement
// 4. change contents based upon HistoryToken found
...
}
-121--4244906- Спасибо за ввод в проблему, и да, я сказал, что не хочу, чтобы за решением стоял код, однако в то время я так что я в итоге воспользовался событием TreeView_SelectedItemChanged.
Хотя подход Уилла кажется хорошей работой вокруг, для моей личной ситуации я решил, что буду использовать код позади. Причина этого заключается в том, что представление и XAML останутся такими же, как если бы TreeViewItem имел свойство «Command», к которому может быть привязана команда. Теперь мне не нужно изменять шаблоны или представления, все, что мне нужно сделать, это добавить код и событие для TreeView_SelectedItemChanged.
Мое решение:
private void TreeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
if (sender != null)
{
var treeView = sender as TreeView;
if (treeView != null)
{
var commandViewModel = treeView.SelectedItem as CommandViewModel;
if (commandViewModel != null)
{
var mi = commandViewModel.Command.GetType().GetMethod("Execute");
mi.Invoke(commandViewModel.Command, new Object[] {null});
}
}
}
}
Поскольку к TreeViewItem уже присоединена команда RelayCommand, все, что я сейчас делаю, это просто вручную вызвать метод «Execute» для этой конкретной команды RelayCommand.
Если это совершенно неправильный способ сделать это, пожалуйста, дайте мне знать...
Спасибо!
Это хороший пример того, как MVVM сильно пострадали в WPF. Вы ожидаете, что для некоторых элементов графического интерфейса будет поддержка Command, но ее нет, поэтому вы вынуждены пройти сложный процесс (как показано в примере Уилла) только для того, чтобы прикрепить команду к чему-либо.
Будем надеяться, что они исправят это в WPF 2.0: -)
Я бы сделал заголовок TreeViewItem как кнопку, а затем скинул бы кнопку так, чтобы она не ' не выглядеть или действовать как один, а затем выполнить привязку моей команды к кнопке.
Возможно, вам придется сделать это с помощью DataTemplate или изменить шаблон самого TreeViewItem. Никогда этого не делал, но вот как я делал похожие вещи (например, заголовки вкладок).
Вот пример того, о чем я говорю (вы можете бросить это в Kaxaml и поэкспериментировать с ним):
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Page.Resources>
<Style x:Key="ClearButan" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Name="border"
Padding="4"
Background="transparent">
<Grid >
<ContentPresenter HorizontalAlignment="Center"
VerticalAlignment="Center">
</ContentPresenter>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Page.Resources>
<Grid>
<TreeView>
<TreeViewItem>
<Button Style="{StaticResource ClearButan}">
easy peasy
</Button>
</TreeViewItem>
</TreeView>
</Grid>
</Page>
Я создал новый четкий стиль для кнопки. Затем я просто вставляю кнопку в TVI и устанавливаю ее стиль. Конечно, вы можете сделать то же самое с помощью шаблонов данных.