Страницы

Поиск по вопросам

четверг, 2 мая 2019 г.

Повесить команду на событие

Подскажите пожалуйста как можно повесить команду (ICommand) из ViewModel на событие Window.Closed? Ради соблюдения принципов MVVM не хочется пользоваться обычным обработчиком.


Ответ

Используйте EventTrigger в сочетании с InvokeCommandAction из неймспейса Windows.Interactivity

команда USE Sercver в запросе

Господа, прошу объяснить не мыслимое
Есть простой запрос, который у меня работает, и в C# и в МС студии
//c# string slim_sqlquery = "SELECT * FROM sys.Tables"; //Ms SQL Server Management Studio SELECT * FROM sys.Tables
Но на некоторых серверах таблички не находятся, в студии делаю по другому
//Ms SQL Server Management Studio Use MyServerName GO SELECT * FROM sys.Tables
А как это же самое реализовать на c# ?
//p.s. string slim_sqlquery = "Use MyServerName GO SELECT * FROM sys.Tables"; SqlCommand cmd = new SqlCommand(slim_sqlquery, conn_my_servak); SqlDataReader reader = cmd.ExecuteReader();//вот тут лезут ошибки, что SQL запрос надо в 1 строку


Ответ

SqlClient не понимает GO так, как это делает SSMS.
Либо используйте three-part naming
SqlCommand cmd = new SqlCommand("SELECT * FROM MyServerName.sys.Tables", conn_my_servak); SqlDataReader reader = cmd.ExecuteReader();
Либо вынесите смену контекста в отдельную команду:
conn_my_servak.ChangeDatabase("MyServerName");
SqlCommand cmd = new SqlCommand("SELECT * FROM sys.Tables", conn_my_servak); SqlDataReader reader = cmd.ExecuteReader();

Как добиться однородного фона (TextView внутри CardView)?

В моей программе мне нужно использовать TextView внутри Cardview из библиотеки поддержки. Нужны скругленные углы. Нужно иметь возможность изменять цвет элемента программно. Следующий код:

приводит к такому результату:

Эти странные полосы и черточки меня совершенно не устраивают.
Следующий же код:

приводит к другому результату:

Второй результат мне не подходит из-за белых краев.
Третья моя попытка: Создала файл rownded_corners.xml в папке drawable

и в разметке второй попытки задала его в качестве фона TextView
android:background="@drawable/rounded_corner"
Вот что получилось:

Здесь меня не устраивает белая рамка.
В общем, вопрос: Как мне добиться однородного цвета, заполняющего весь CardView, и сохранить возможность программно установить другой цвет.
UPDATE. Описанное в вопросе недоразумение уже разрешилось. См. мой ответ.


Ответ

Представляете, описанное в вопросе недоразумение было вызвано тем, что используемый мною цвет (colorPrimary) был полупрозрачным (что-то вроде #a03F51B5) и через него была видна "кухня" построения CardView. Я изменила его на #3F51B5 и первый вариант дал желаемый результат даже без атрибута, предложенного @ЮрийСПб.

Работа с XML в MS SQL?

Допустим, есть XML такого вида:

Можно ли получить выборку такого вида?
value --------------- значение field1 значение field2 значение field3 значение field1 значение field2 значение field3
Можно ли это сделать без явного перечисления названия узлов? Допустим, известно, что все узлы field+цифра. Можно ли сделать запрос по маске?


Ответ

Вы можете отфильтровать узлы с нужными именами с помощью функций local-name и substring
declare @xml xml = N' value 1 value 2 value 3 AA value 4 value 5 value 6 BB ';
select x.c.value('text()[1]', 'varchar(20)') value from @xml.nodes('/root[1]/TableRow/*[substring(local-name(), 0, 6)="field"]') x(c);
Результат:
value -------- value 1 value 2 value 3 value 4 value 5 value 6
В XQuery запросах использовать * в XPath (также как и выражения наподобие '//field'), если без них можно обойтись, не рекомендуется. Если выбираете узлы от корня, то лучше указать '/root[1]' в начале XPath. Если точно известен путь до узлов - указывайте его явно. Если берёте значение из элемента, то лучше взять его не через , а через text()[1]. Чем больше информации об узлах вы дадите XQuery процессору, тем проще будет ему распарсить xml и тем ниже будет стоимость запроса.
В данном случае, например, оценочная стоимость такого запроса
select x.c.value('text()[1]', 'varchar(20)') value from @xml.nodes('/root[1]/TableRow/*[substring(local-name(), 0, 6)="field"]') x(c);
и такого
select x.c.value('.', 'varchar(20)') value from @xml.nodes('*/*/*[substring(local-name(), 0, 6)="field"]') x(c);
соотносятся примерно как 2 к 136.

Как создать типизированный массив объектов?

Предыстория: пишу свою реализацию коллекции на основе массива (задание такое). И дошел до метода toArray()
Есть классический массив:
private E[] array;
как его проинициализировать так что бы когда я возвращаю этот массив он был не Object а именно того типа который поступил на вход в класс.
Такой вариант при возвращении все равно возвращает Object[]
array =(E[]) new Object[length]
Просмотрел уже несколько лекций по дженерикам в джаве и основная суть ясна, но нигде не говорят о типизированных массивах.


Ответ

Тут есть подробное описание проблемы на английском языке.
Вроде должно сработать как-то так:
public E[] getArray(Class clazz, int size) { @SuppressWarnings("unchecked") E[] arr = (E[]) Array.newInstance(clazz, size);
return arr; }

Как исполнить скрипт при запуске docker-контейнера?

Здравствуйте!
Вопрос, возможно, несколько избит, но ответа на него я не нашел. А похожие вопросы на тостере, как в и гугле не помогли. Я буду премного благодарен тем людям, что уделят немного своего времени и дадут развернутый ответ!
И так, задача минимум - запустить apache при старте контейнера
Задача максимум - выполнить bash скрипт при старте контейнера
Я опишу варианты которые я пробовал.
1. Сборка простейшего образа и запуск контейнера из консоли
Dockerfile FROM ubuntu:14.04
RUN apt-get update && \ apt-get install -y apache2
В консоли: sudo docker build -t apache . sudo docker run -dit --name cont_apache apache /bin/bash service apache2 start
В ответ код контейнера, docker ps чист. docker logs cont_apache сообщает о запуске апача - Starting web server apache2 ... Но сам контейнер почему-то умирает. хотя флаг -d установлен.
Попытался: sudo docker run -dit --name cont_apache apache service apache2 start
Результат точно такой же.
2. Сборка образа и запуск апача при помощи CMD
Dockerfile: FROM ubuntu:14.04
RUN apt-get update && \ apt-get install -y apache2
CMD ["service" "apache2", "start"]
В консоли: sudo docker build -t apache . sudo docker run -dit --name cont_apache apache /bin/bash service apache2 start
Контейнер запущем, висит как демон, перехожу в контейнер: root@2a97628fd78b:/# service apache2 status * apache2 is not running Апач не запустился. Почему?
3. Сборка образа с проброской bash скрипта и его выполнение
Dockerfile: FROM ubuntu:14.04
RUN apt-get update && \ apt-get install -y apache2
COPY ./apache2_start.sh /root/apache2_start.sh
CMD ["chmod", "777", "/root/apache2_start.sh"]
CMD ["/root/apache2_start.sh"]
Script apache2_start.sh: #!/bin/bash
service apache2 start echo "127.0.0.1"
В консоли: sudo docker build -t apache . sudo docker run -dit --name cont_apache apache
В docker ps контейнера нет. В логах docker logs cont_apache: * Starting web server apache2 AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 172.17.0.3. Set the 'ServerName' directive globally to suppress this message * 127.0.0.1
Пробовал также с запуском bash из консоли: sudo docker run -dit --name cont_apache apache /bin/bash
В результате контейнер висит в docker ps. Docker logs conf_apache чист.
А в самом контейнере: root@d2c9831773a9:/# service apache2 status * apache2 is not running
Итог.
Я попытался добиться нужного результата разными способами, но ни одним у меня не вышло.
Очевидно, что я допускаю ошибки в работе с докером.
Я буду очень! благодарен за конструктивную помощь в данном вопросе как в целом, так и что в каком конкретном случае я делал не так.
Конечно, эти примеры высосаны из пальца, и можно найти кучу примеров запуска окружения при помощи docker compose. Но моя цель разобраться в вопросе, и уже в дальнейшем использовать всякие крутые штуки вроде docker compose


Ответ

Докер-контейнер - это один процесс, обернутый в изолированную среду. Этот процесс может порождать дочерние процессы, но основной постулат остается одинаковым: время жизни контейнера - это время жизни процесса, указанного в ENTRYPOINT/CMD. Насколько понимаю, команда apache2 service start попытается запустить апач в фоновом режиме и тут же закончит свое выполнение; как только докер увидит, что процесс закончился, он прибьет контейнер. Таким образом, ваша конечная цель - выполнить в начале скрипта требуемые действия, а потом сделать так, чтобы он выполнялся все время жизни приложения (в случае с апачем - условно бесконечно). Проще всего это сделать следующим образом:
выполнить требуемые действия последней командой в шелл-скрипте запустить апач с отключенным фоновым режимом (-DFOREGROUND), предварив команду инструкцией exec. Эта инструкция позволит текущему процессу (выполняющемуся шелл-скрипту) стать процессом, вызванным exec. После этого ctrl-c и прочие плюшки будут отправляться на обработку напрямую апачу.
пример такой работы можно увидеть прямо в официальном изображении library

Как вычислить координаты всех точек лежащих на окружности


Предположим мне нужны координаты 360 точек на окружности, по одной на каждый градус поворота
Есть предположение:
int x = (int)Math.Cos(2 * Math.PI * i / n) * R + x[0]; int y = (int)Math.Sin(2 * Math.PI * i / n) * R + y[0];
Где i - номер точки, n - кол-во точек = 360, R - радиус, x[0] и y[0] - координаты центра окружности
Вот только таким способом вычисляются только эти четыре точки:

Как пройтись по всем 360-ти точкам?


Ответ

int x = (int)Math.Cos(2 * Math.PI * i / n) * R + x[0]; int y = (int)Math.Sin(2 * Math.PI * i / n) * R + y[0];
Я предполагаю, что нужны именно целочисленные координаты. В таком случае следует выполнять округление после умножения на радиус.
int x = (int)(Math.Cos(2 * Math.PI * i / n) * R + 0.5) + x0; int y = (int)(Math.Sin(2 * Math.PI * i / n) * R + 0.5) + y0;
Это по-прежнему не гарантирует, что получатся все 360 точек, но теперь их не всегда будет 4.
http://ideone.com/fxzB8V
4 of 360 when radius is 1 76 of 360 when radius is 10 140 of 360 when radius is 20 268 of 360 when radius is 40 356 of 360 when radius is 80 360 of 360 when radius is 90 360 of 360 when radius is 100
Если же целочисленные координаты не требуются, то вместо int следует использовать double:
double x = Math.Cos(2 * Math.PI * i / n) * R + x0; double y = Math.Sin(2 * Math.PI * i / n) * R + y0;