não pode envolver minha cabeça em torno de ligação de dados do WPF

votos
0

Meu cenário: Um formulário WPF tem uma caixa de texto e um WPF toolkig datagrid . Quando um texto é inserido na caixa de texto, o meu serviço retorna uma IEnumerable<TranslationItem>itens. Eu quero o meu datagrid para mostrar o resultado deste serviço.

Eu tentei googling ao redor, mas não posso ficar cara ou coroa para ele. Eu estou apenas começando a aprender WPF ea maioria dos termos usados me iludir.
O que eu reunir é que eu deveria colocar o resultado do meu serviço em uma ObservableCollection, sem suor. Mas então eu quero vinculá-lo de alguma forma para o meu datagrid. Como eu posso fazer isso? Como é que a grade saber o que colunas para gerar?

Publicado 19/05/2009 em 16:18
fonte usuário
Em outras línguas...                            


4 respostas

votos
3

O que eu reunir é que eu deveria colocar o resultado do meu serviço em uma ObservableCollection, sem suor. Mas então eu quero vinculá-lo de alguma forma para o meu datagrid. Como eu posso fazer isso?

A maneira mais fácil é para definir a propriedade ItemsSource de DataGrid para o ObservableCollection.

Como é que a grade saber o que colunas para gerar?

O DataGrid reflete os objetos em que a coleta e criar uma coluna para cada propriedade pública que encontra. Veja aqui para mais informações.

Se você definir a propriedade ItemsSource diretamente, então não é realmente wpf vinculativo. Aqui está três links que eu encontrei útil quando eu comecei a ligação de dados no WPF.

Bea Stollnitz: O que significa “{Binding}” significa?
WPF Dados básicos Encadernação FAQ
MSDN: Ligação de dados Tópicos de instruções

Respondeu 19/05/2009 em 17:26
fonte usuário

votos
2

Enquanto um ObservableCollection pode ser usado para isso, dependendo de como ele é usado você não vai receber qualquer benifit dele. A característica fundamental do ObservableCollection é que ele implementa INotifyCollectionChanged. O que essa interface faz é fornecer um mecanismo de notificação por dizer ao UI que uma propriedade mudou. Desde ObservableCollection já implementa isso, se você ligar o seu DataGrid, ListBox, ItemsControl, de etc. propriedade ItemSource a uma coleção deste tipo ele irá automaticamente atualizar a interface do usuário sempre que um item é adicionado / removido / substituído / movido / Reset. Devido a isso, cada vez que você deseja atualizar a coleção com um novo conjunto de resultados IEnumerable, você terá que primeiro limpar a coleção, e depois adicionar os novos resultados.

No entanto, não há outra opção que eu recomendaria mais de uma ObservableCollection neste caso. Ele é usar algo chamado um ObjectDataProvider. Usando isto, podemos evitar o código por trás inteiramente, e é em geral muito mais limpo. Portanto, temos o nosso serviço em algum lugar, neste caso em meus Window.xaml.cs

public class TranslationService
{
    public IEnumerable<string> Translate(string s)
    {
        return s.ToCharArray().Select(c => c.ToString());
    }
}

Como o serviço que você descreve, é preciso que uma corda de uma caixa de texto, e retorna um IEnumerable. Agora, no XAML podemos usar este serviço e fazer chamadas para ele.

Nos declerations janela, podemos adicionar o namespace para onde o serviço está localizado:

 xmlns:local="clr-namespace:WpfApplication4"

Agora, em nossos Window.Resources (ou UserControl, ou em qualquer outro lugar), podemos referenciar o nosso serviço. Uma vez que tenhamos exposto o nosso serviço como um recurso, podemos criar um ObjectDataProvider que expõe o método Traduzir queremos usar.

<Window.Resources>
    <local:TranslationService x:Key="MyTranslationService" />
    <ObjectDataProvider x:Key="MyProvider"
                        ObjectInstance="{StaticResource MyTranslationService}"
                        MethodName="Translate">
        <ObjectDataProvider.MethodParameters>
            ""
        </ObjectDataProvider.MethodParameters>
    </ObjectDataProvider>
</Window.Resources>

O ObjectDataProvider é introduzido ao nosso serviço e chama o método Traduzir com um parâmetro de cadeia. Agora tudo o que temos a fazer é que ele comece a responder à nossa caixa de texto.

Podemos fazer isso, fazendo uso de algumas das propriedades de ligação. Queremos que a nossa TextProperty na caixa de texto para se ligar ao ObjectDataProvider, para que defina a propriedade Fonte para apontar para ele. A parte do ObjectDataProvider que queremos vincular a, no caminho, é o MethodParameter. Agora, nós configurá-lo para vincular diretamente à fonte daquela propriedade, e viajar apenas um caminho, o que significa que parâmetro do método do ObjectDataProvider não irá atualizar o texto do TextBox. Finalmente, podemos definir o UpdateSourceTrigger para PropertyChanged, contando a ligação para definir a fonte que estamos a ligação a, no provedor de dados objeto, sempre que houver qualquer alteração ao texto.

<StackPanel>
        <TextBox TextChanged="OnTextChanged"
            Text="{Binding Source={StaticResource MyProvider}, Path=MethodParameters[0], BindsDirectlyToSource=True, Mode=OneWayToSource, UpdateSourceTrigger=PropertyChanged}" />
        <ListBox ItemsSource="{Binding Source={StaticResource MyProvider}}" />
    </StackPanel>

Tudo o que resta é definir o ItemsSource na grelha, ou uma caixa de listagem simples neste caso.

Em relação à parte final sobre o DataGrid: Se você estiver usando grade de dados do WPFToolkit, ele tem uma auto característica que pode ser ajustado através das propriedades geram, e você pode encontrar mais informações sobre ele aqui .

Respondeu 20/05/2009 em 08:27
fonte usuário

votos
0

sua grade pode construir as colunas diretamente, ou você pode especificar os tipos de colunas que você deseja. Se você assistir a este vídeo , ele vai explicar isso. Isso é para VS2010, mas os fundamentos são os mesmos para VS2008 - embora a implementação é apenas um pouco diferente, uma vez que não é tão integrado.

Quanto à forma de ligar, atribuir o ObservableCollection que mantém seus itens para a propriedade ItemsSource do grid.

Respondeu 19/05/2009 em 16:24
fonte usuário

votos
0

Você define o DataSource (ou mesmo o DataContext) da grelha para a sua coleção observável.

Eu não estou familiarizado com essa grade de dados, mas a maioria das redes tem opções para qualquer expor todas as propriedades públicas do tipo na coleção observável como colunas, ou você definir explicitamente um layout de coluna em XAML e uma das propriedades da definição de coluna é a propriedade do objecto a ser usado para os dados da coluna.

por exemplo, com Infragistics grade de dados

                <igDP:Field Name="OrderSize" Label="Order Size">
                    <igDP:Field.Settings >
                        <igDP:FieldSettings CellWidth="75">
                            <igDP:FieldSettings.EditorStyle>
                                <Style TargetType="{x:Type Editors:ValueEditor}" >
                                    <Style.Setters>
                                        <Setter Property="Format" Value="#,##0"/>
                                    </Style.Setters>
                                </Style>
                            </igDP:FieldSettings.EditorStyle>
                        </igDP:FieldSettings>
                    </igDP:Field.Settings>
                </igDP:Field>

Nome é onde você define a propriedade sobre o objeto para usar.

Respondeu 19/05/2009 em 16:22
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more