3

Имеется источник данных и DataGrid. Нужно заполнить последнюю колонку ссылками, ссылки будут однотипные примера somesite.ru/user?id=ID, где id берестся из ItemSource. Все никак с Binding разобраться не могу.

<dxg:GridControl Name="grid" Grid.Row="1" FontFamily="Geometria" FontSize="10" >
        <dxg:GridControl.Columns>
            <dxg:GridColumn FieldName="Название" />
            <dxg:GridColumn FieldName="Издательство" />
            <dxg:GridColumn FieldName="Цена" />
            <dxg:GridColumn FieldName="Просмотры" />
            <dxg:GridColumn FieldName="Рейтинг" Width="100"/>
            <dxg:GridColumn>
                <dxg:GridColumn.CellTemplate>
                    <DataTemplate>
                        <StackPanel HorizontalAlignment="Center">
                            <!--тут ссылка-->
                        </StackPanel>
                    </DataTemplate>
                </dxg:GridColumn.CellTemplate>
            </dxg:GridColumn>
        </dxg:GridControl.Columns>
        <dxg:GridControl.View>
            <dxg:TableView NavigationStyle="Cell" FocusedRowChanged="TableView_FocusedRowChanged" AllowEditing="False">

            </dxg:TableView>
        </dxg:GridControl.View>
    </dxg:GridControl>

2 Answers2

4

А что сложного?

Создаёте конвертер:

class UriConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter,
                          CultureInfo culture)
    {
        var id = (string)value;
        return new Uri("http://somesite.ru/user?id=" + id);
    }

    public object ConvertBack(object value, Type targetType, object parameter,
                              CultureInfo culture)
    {
        throw new NotSupportedException();
    }
}

Затем, положите его в ресурсы вашего окна:

<Window.Resources>
    <local:UriConverter x:Key="UriConverter"/>
</Window.Resources>

И используйте для конвертации:

<TextBlock>
    <Hyperlink
        NavigateUri="{Binding Mode=OneWay, Converter={StaticResource UriConverter}}"
        RequestNavigate="OnRequestNavigate"><Run Text="{Binding NavigateUri,
            RelativeSource={RelativeSource FindAncestor, AncestorType=Hyperlink}}"/></Hyperlink>
</TextBlock>

Подписка на RequestNavigate нужна для того, чтобы работали ссылки.

void OnRequestNavigate(object sender, System.Windows.Navigation.RequestNavigateEventArgs e)
{
    var uri = e.Uri.AbsoluteUri;
    Task.Run(() => Process.Start(uri));
    e.Handled = true;
}

Вроде бы всё, должно работать.

VladD
  • 206,799
  • То есть получается в UriConverter попадает значение из базы? Не подскажете хороший источник информации по Binding. – Илья Jun 16 '16 at 02:01
  • @Илья, в конвертер там попадает значение текущей строки текущего столбца. Откуда оно там берется в вашем случае - непонятно. Но, видимо, из базы :) – iRumba Jun 16 '16 at 05:25
  • В UriConverter попадает то, что приходит после Binding. В вашем случае — id. По поводу что почитать, я бы посоветовал книги отсюда. Например, WPF Unleashed, Adam Nathan. – VladD Jun 16 '16 at 10:32
2

А еще проще через форматирование

вот как выглядит биндинг

{Binding YourProperty, StringFormat='somesite.ru/user?id={0}'}

Ну а в вашем случае просто

{Binding StringFormat='somesite.ru/user?id={0}'}

Короче все то же самое, что написал VladD, только без конвертера

iRumba
  • 5,946
  • А если например в эту ячейку записывать значения из других ячеек грида той же строки – Илья Jun 16 '16 at 05:36
  • @Илья Для этого есть MultiBinding. Но в вашем случае я не уверен как лучше это сделать. Вы используете контролы DevExpress, а я их не очень то знаю :) Общий смысл в том, что значения ячеек нужно проставлять не через FieldName, а через TextBlock + binding, тогда вы сможете взять хоть все значения через мультибиндинг и так же вставить их в ссылку через StringFormat – iRumba Jun 16 '16 at 05:40
  • @iRumba: Это работает, если Binding идёт к полю типа string. Но с NavigateUri типа Uri это не сработает. Я пробовал тоже вначале :) – VladD Jun 16 '16 at 10:36
  • @VladD, так там по любому стринг. Это же таблица и данные скорее всего подтянуты из DataTable – iRumba Jun 16 '16 at 14:24
  • @iRumba: Вроде бы Hyperlink.RequestUri не стринг. Вопрос не в источнике данных, а в том, куда они биндятся. Попробуйте! – VladD Jun 16 '16 at 14:37
  • @VladD, да, вы правы. А вообще, это, конечно, ИМХО, но я бы все же делал это во вью модели. Без конвертера. Создал бы вычисляемый столбец (или свойство, если источником данных является коллекция из экземпляров класса) – iRumba Jun 17 '16 at 02:55
  • @iRumba: Правильная мысль, кстати. Составление URI из id — не задача уровня UI. Может, напишете об этом в ответе? Это важное рассуждение. – VladD Jun 17 '16 at 08:37
  • @VladD, тут ваш ответ признан ответом, его и будут читать. Так что уж лучше в своем ответе это добавьте. Так эту мысль прочитает больше народу ;) – iRumba Jun 20 '16 at 04:37
  • @iRumba: Идея по справедливости ваша, так что пусть лучше она будет у вас. А кто не читает альтернативные ответы, сам виноват. – VladD Jun 20 '16 at 07:57