Использование MS ReportViewer в WPF

Обновление: элегантное решение (любезно предоставлено Крисом Пруденом и Синдром Сорхусом)

Решение основано на этом коммите Криса в библиотеке Синдре 'on-change' ]. [1 123]

Объяснение решения Крисом:

В ловушке set моя цель - определить, является ли предоставленное значение Proxy, созданным предыдущий вызов в ловушку get. Если это такой Proxy, любой доступ к свойству будет перехвачен нашей собственной get ловушкой. Поэтому, когда я получу доступ к value[proxyTarget], будет вызвана наша get ловушка, которая закодирована так, чтобы возвращать target при property === proxyTarget (строка 46). Если значение, переданное в set, не является прокси-сервером, созданным при изменении, тогда value[proxyTarget] будет undefined.

blockquote>

Полный код решения:

(object, onChange) => {
    let inApply = false;
    let changed = false;

    function handleChange() {
        if (!inApply) {
            onChange();
        } else if (!changed) {
            changed = true;
        }
    }

    const handler = {
        get(target, property, receiver) {
            const descriptor = Reflect.getOwnPropertyDescriptor(target, property);
            const value = Reflect.get(target, property, receiver);

            // Preserve invariants
            if (descriptor && !descriptor.configurable) {
                if (descriptor.set && !descriptor.get) {
                    return undefined;
                }
                if (descriptor.writable === false) {
                    return value;
                }
            }

            try {
                return new Proxy(value, handler);
            } catch (_) {
                return value;
            }
        },
        set(target, property, value) {
            const result = Reflect.set(target, property, value);

            handleChange();

            return result;
        },
        defineProperty(target, property, descriptor) {
            const result = Reflect.defineProperty(target, property, descriptor);

            handleChange();

            return result;
        },
        deleteProperty(target, property) {
            const result = Reflect.deleteProperty(target, property);

            handleChange();

            return result;
        },
        apply(target, thisArg, argumentsList) {
            if (!inApply) {
                inApply = true;
                const result = Reflect.apply(target, thisArg, argumentsList);
                if (changed) {
                    onChange();
                }
                inApply = false;
                changed = false;
                return result;
            }

            return Reflect.apply(target, thisArg, argumentsList);
        }
    };

    return new Proxy(object, handler);
};

Это решило мою проблему, не прибегая к взлому проверки методов модификации массива.


Исходное решение:

Пока что я отсортировал это с помощью сообщения Дэвида Уолша здесь . Это все еще уродливо, но пока работает.

Обновлен создатель прокси onChanged с ловушкой рекурсивного выхода get.

get: function (target, property, receiver) {
    let retval;

    try {
        retval = new Proxy(target[property], handler);
    } catch (err) {
        retval = Reflect.get(target, property, receiver);
    }

    if (mutators.includes(property))
        onChange(target, property, receiver);

    return retval;
},

Также добавлен список функций для проверки ловушки get (некрасивый, хакерский бит):

const mutators = [
    "push",
    "pop",
    "shift",
    "unshift",
    "splice",
    "reverse",
    "fill",
    "sort"
]

Это, кажется, работает в моем тестировании до сих пор.

Спасибо, что указали в правильном направлении.

31
задан Mitch 7 May 2009 в 23:59
поделиться

2 ответа

Мы определенно добились успеха, просто используя WindowsFormsHost. Я не участвовал в создании самих файлов RDLC, но я считаю, что они были разработаны (как вы говорите) в проекте WinForms, а затем скопированы.

Обратите внимание, что если вам не нужны локальные отчеты, вы можете использовать Элемент управления WPF Frame и укажите его на URL-адресе серверного отчета (он отображает его так, как это делает веб-браузер). Это очень хорошо работает и для нас.

23
ответ дан 27 November 2019 в 22:24
поделиться

Да, это работает, я использую WindowsFormsHost в проекте wpf, чтобы обернуть ReportViewer.

В ViewModel я создаю WindowsFormsHost и ReportViewer:

WindowsFormsHost windowsFormsHost = new WindowsFormsHost();
reportViewer = new ReportViewer();
windowsFormsHost.Child = reportViewer;
this.Viewer = windowsFormsHost

а в View я использую ContentPresenter для его отображения путем привязки к свойству, содержащему WindowsFormsHost.

 <ContentPresenter Content="{Binding Viewer}" ...

Мы используем Business Intelligence Studio (Visual Studio 2008 с шаблонами для редактирования отчетов) для создания отчетов. http://msdn.microsoft.com/en-us/library/ms173767.aspx

Береги себя,
Мартин

25
ответ дан 27 November 2019 в 22:24
поделиться
Другие вопросы по тегам:

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