WPF DataTemplate и привязка

В ответ на Mike B, я предпочитаю использовать 'класс' как в шаблоне, 'имя типа' имеет перегруженное значение, но 'класс' не делает. Возьмите этот проверенный пример целого типа:

template 
class smart_integer {
public: 
    typedef integer_traits traits;
    IntegerType operator+=(IntegerType value){
        typedef typename traits::larger_integer_t larger_t;
        larger_t interm = larger_t(myValue) + larger_t(value); 
        if(interm > traits::max() || interm < traits::min())
            throw overflow();
        myValue = IntegerType(interm);
    }
}

larger_integer_t зависимое имя, таким образом, оно требует, чтобы 'имя типа' предшествовало ему так, чтобы синтаксический анализатор мог распознать, что larger_integer_t тип. класс , на otherhand, не имеет такого перегруженного значения.

, Что... или я просто ленив в глубине души. Я ввожу 'класс' намного чаще, чем 'имя типа', и таким образом нахожу намного легче ввести. Или это мог быть знак, что я пишу слишком много кода OO.

6
задан John Saunders 15 July 2009 в 01:20
поделиться

3 ответа

As you said, the DataContext is set to the ViewModel class so the control that you mentioned in XAML will be able to access the public properties of that ViewModel.

For example:

private ObservableCollection<Commander> commands = new ObservableCollection<Commander>();

    public ObservableCollection<Commander> Commands {
        get { return commands; }
        set { commands = value; }
    }

The structure of Commander class.

public class Commander {
    public ICommand Command { get; set; }
    public string DisplayName { get; set; }
}

That VM has the property called Commands which might be ObservableCollection. This property can be accessible from XAML.

You can imagine that HeaderedContentControl is a container. The content of that HeaderedContentControl is a DataTemplate "CommandsTemplate" that has a ItemsControl and it bind to the Commands property of VM.

Content="{Binding Path=Commands}"

And then, you can to bind ItemControl with Commands again but that ItemControl is inside the content that bind to Commands. So you don't need to specify the path again. You can just use

 ItemsSource="{Binding}" instead of ItemsSource="{Binding Commands}".

Two textblocks are inside ItemControl so they are at the same level as Commander class of Commands ObservableCollection. That's why you can access Text="{Binding Path=DisplayName}" directly.

Hope it helps.

9
ответ дан 9 December 2019 в 22:38
поделиться

Привязка ItemsSource к {Binding} привязывается непосредственно к DataContext элемента ItemsControl (который будет искать в цепочке, пока не найдет установленный DataContext). В этом случае он был установлен в HeaderedContentControl

. Каждый элемент внутри ItemsControl будет иметь свой DataContext, установленный на элемент в списке.

устанавливает шаблон для каждого элемента внутри списка, а не для самого элемента ItemsControl. Так что {Binding Path = Command} и {Binding Path = DisplayName} будут проверять эти свойства элементов внутри списка.

1
ответ дан 9 December 2019 в 22:38
поделиться

Пример:

XAML

<Window x:Class="WpfApplication2.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" Loaded="Window_Loaded">
    <Window.Resources>
        <DataTemplate x:Key="CommandsTemplate">
            <ItemsControl IsTabStop="False" ItemsSource="{Binding}" Margin="6,2">
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <TextBlock Margin="2,6">pou
                            <Hyperlink Command="{Binding Path=Command}">
                                <TextBlock Text="{Binding Path=DisplayName}" />
                            </Hyperlink>
                        </TextBlock>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
        </DataTemplate>
    </Window.Resources>
    <Grid>
        <Border Width="170">
            <HeaderedContentControl
                Content="{Binding Path=Commands}"
                ContentTemplate="{StaticResource CommandsTemplate}"
                Header="Control Panel"/>
        </Border>
    </Grid>
</Window>

C #

/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class Window1 : Window {
    public Window1() {
        InitializeComponent();

        Commands.Add(new Commander() { DisplayName = "DN1" });
        Commands.Add(new Commander() { DisplayName = "DN2" });
        Commands.Add(new Commander() { DisplayName = "DN3" });

        this.DataContext = this;
    }

    private void Window_Loaded(object sender, RoutedEventArgs e) {

    }

    private ObservableCollection<Commander> commands = new ObservableCollection<Commander>();

    public ObservableCollection<Commander> Commands {
        get { return commands; }
        set { commands = value; }
    }
}

public class Commander {
    public ICommand Command { get; set; }
    public string DisplayName { get; set; }
}
1
ответ дан 9 December 2019 в 22:38
поделиться
Другие вопросы по тегам:

Похожие вопросы: