Все технические форумы на одном сайте Удобный поиск информации с популярных форумов в одном месте
Вопрос: WCF: Всё ли я правильно понимаю и делаю?

Всем привет. Вот уже который день разбираюсь с wcf... Возникло несколько вопросов, в которых вроде как разобрался, но хотелось бы быть уверенным) Буду очень признателен если поможете расставить все точки над и.

1. Сейчас сделал библиотеку (сам сервис) и консольку self hosting, откуда сейчас сервис запускается. Решил, что это хороший вариант для отладки и тестирования. Гладко ли потом я смогу перевести wcf на IIS (в консольке только .Open настройка в конфиге)?

2. Долго пытался выбрать между http и tcp... Сейчас пришёл к тому, что реализовал и то и то:
XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
  <system.serviceModel>
    <services>
      <service behaviorConfiguration="mexBehavior" name="WcfKeysService.KeysService">
        <endpoint address="KeysService" behaviorConfiguration="webBehavior"
              binding="webHttpBinding" contract="WcfKeysService.IKeysService">
        </endpoint>
        <endpoint address="KeysService" binding="netTcpBinding" bindingConfiguration="" contract="WcfKeysService.IKeysService" />        
        <host>
          <baseAddresses>
            <add baseAddress="http://192.168.0.48:8080/KeysService" />
            <add baseAddress="net.tcp://192.168.0.48:8090/KeysService" />
          </baseAddresses>
        </host>
      </service>
    </services>
    <behaviors>
      <endpointBehaviors>
        <behavior name="webBehavior">
          <webHttp defaultOutgoingResponseFormat="Json" />
        </behavior>
      </endpointBehaviors>
      <serviceBehaviors>
        <behavior name="mexBehavior">
          <serviceMetadata httpGetEnabled="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
Почему так? http - что бы в перспективе можно было реализовать мультиплатформенность клиентского ПО. Сделал ещё тестовую консоль клиента с Service References. Я так понял там используется tcp, потому что подключаюсь следующим образом:
C#
1
KeysService.KeysServiceClient serv = new KeysService.KeysServiceClient();
Очень удобно. Я так понимаю плюсом этого подхода остаётся то, что тут есть сессия и он вроде как быстрее. Вопрос в следующем: нужно ли мне tcp если мне сессии не нужны, а просто получение/отправка данных?

3. Для того, что бы методы отрабатывали в браузере OperationContractу нужно добавить флаг [WebGet]. Что бы метод работал и на http и на tcp нужно их дублировать?

4. Следующий кусок не работает:
C#
1
2
        [OperationContract]
        bool Initialization(int login, int size);
Ругается, что тут 2 параметра. Если это [WebGet], то решается проблема легко, а вот для меня конкретного решения не нашёл. Добавил DataContract:
C#
1
2
3
4
5
6
7
8
9
    [DataContract(Namespace = "")]
    public class RequestInit
    {
        [DataMember]
        public int login { get; set; }
 
        [DataMember]
        public int size { get; set; }
    }
Заработало, но правильно ли я сделал? Или можно было просто сделать класс?

5. Что лучше при написании клиентского ПО добавлять ссылку на службу (как я сделал) или вынести контракты в отдельную dllку и подключать её?

6. Ну и последний размытый вопрос... Есть какие-нибудь способы администрирования сервиса? Ну тоесть изменение каких-нибудь статичных переменных, точнее наверное выполнение методов, недоступных остальным юзерам...

Добавлено через 6 минут
7. Можете что-нибудь скинуть , где понятным языком написано про реализацию асинхронности в wcf?.. Ещё не начинал этим заниматься, но думаю стоит. Ну и вообще как работает wcf? В один поток и всё блочится, когда для 1 соединения выполняется какая-нибудь длительная операция?
Ответ:
Сообщение от awp-sirius
Гладко ли потом я смогу перевести wcf на IIS (в консольке только .Open настройка в конфиге)?
Без особых проблем.
Сообщение от awp-sirius
нужно ли мне tcp если мне сессии не нужны, а просто получение/отправка данных?
TCP, как правило, используется в локальной сети для межмашинных коммуникаций, когда на обеих сторонах приложения на Windows. Плюс - более высокая скорость, за счет бинарной кодировки (кстати, ее можно и для HTTP использовать).
HTTP - для работе в интернете, с использованием клиентов на разных платформах.
Сообщение от awp-sirius
Что бы метод работал и на http и на tcp нужно их дублировать?
WebGet, WebInvoke используется в WCF HTTP, поэтому TCP тут не при чем.
Сообщение от awp-sirius
Заработало, но правильно ли я сделал? Или можно было просто сделать класс?
Вопрос не совсем понятен, работать должно и так, и эдак. Все зависит от того, как в контракте определена данная операция.
Сообщение от awp-sirius
Что лучше при написании клиентского ПО добавлять ссылку на службу (как я сделал) или вынести контракты в отдельную dllку и подключать её?
Зависит от ситуации, тут никаких советов нет.
Сообщение от awp-sirius
Ну и последний размытый вопрос...
Вопрос действительно очень размытый, конкретизируйте, что вы хотите узнать.
Сообщение от awp-sirius
Можете что-нибудь скинуть , где понятным языком написано про реализацию асинхронности в wcf?.. Ещё не начинал этим заниматься, но думаю стоит. Ну и вообще как работает wcf?
Могу посоветовать список книг, их должно хватаить, а далее - MSDN.
По асинхронности - WCF на стороне службы работает в потоках из пула, поэтому там явно писать асинхронный код нежелательно. Вся асинхронность реализуется на стороне клиента.
В службе для управления параметрами, отвечающими за многопоточность и все что с этим связано, отвечают атрибут ServiceBehavior и его свойства: InstanceContextMode, ConcurrencyMode, ServiceThrottling.
Вопрос: Как получиться datacontext usercontrol?

Доброго времени суток уважаемые знатоки! Вопрос возможно банальный, но никак не могу с ним разобраться.
И так: использую RadGridView от Telerik, привязал коллекцию - все работает. Затем решил добавить фильтр по столбцу - то есть пользователь вводит текст и в гриде строки фильтруются.
Как то так:
<telerik:RadGridView ItemSource="{Binding ListTest}" ...>
<telerik:RadGridView.FilterDescriptors>
<telerik:FilterDescriptor IsCaseSensitive="False" Operator="Contains" Member="t1" Value="{Binding FilterValue}"...


FilterValue - это свойства типа string, куда записывается то, что ввел пользователь в textBox. Но как я понимаю, у грида другой datacontext, а как получиться ссылку на datacontext всего usercontrol? Через ElementName не работает(

Использую MVVM, для dataContext userControl используется отдельный класс. Устанавливается в другом классе))
Ответ: Roman Mejtes,

проверил. Все правильно. В SL не доступен, а в WPF доступен (ради интереса создал тестовое wpf приложение). Вот они "приятные" неожиданности silverlight((

Вопрос обновление source у view решил простым присваиванием)) То есть когда пользователь запрашивает данные с сервера (через webclient в моем случае реализовано) то после того, как ObservableCollection получена она снова присваивается view.source.
Не знаю, правда, насколько этот подход неправильный...
Вопрос: DataTemplate и неявное преобразование

Сегодня захотел облегчить себе жизнь :) как обычно, но всё оказалось не так просто.
Все мы знаем ситуацию, когда надо создать аля CheckBoxList в котором будут перечислены какие то сущности.
Так как сама по себе сущность может не предусматривать свойства IsChecked или какой то подобной, не возможно связывать выделение во View с ViewModel, в результате мы не можем понять, выделены или нет эти объекты.
Я логично предположил, что было бы удобно создать Generic обёртку для таких ситуаций, которая бы просто добавила мне свойство IsChecked, а работать это должно точно так же как и с Nullable<T>.
В результате получился следующий класс:
+
    public class CheckBoxWrapper<T> : IEquatable<CheckBoxWrapper<T>> 
    {
        public bool Equals(CheckBoxWrapper<T> other)
        {
            if (ReferenceEquals(null, other)) return false;
            if (ReferenceEquals(this, other)) return true;
            return EqualityComparer<T>.Default.Equals(_value, other._value);
        }

        public override int GetHashCode()
        {
            return EqualityComparer<T>.Default.GetHashCode(_value);
        }

        public static bool operator ==(CheckBoxWrapper<T> left, CheckBoxWrapper<T> right)
        {
            return Equals(left, right);
        }

        public static bool operator !=(CheckBoxWrapper<T> left, CheckBoxWrapper<T> right)
        {
            return !Equals(left, right);
        }

        private readonly T _value;
        private bool? _isChecked;

        public CheckBoxWrapper(T value)
        {
            _value = value;
        }

        public T Value
        {
            get { return _value; }
        }

        public bool? IsChecked
        {
            get { return _isChecked; }
            set { _isChecked = value; }
        }

        public static implicit operator T(CheckBoxWrapper<T> value)
        {
            return value.Value;
        }

        public static implicit operator CheckBoxWrapper<T>(T value)
        {
            return new CheckBoxWrapper<T>(value);
        }


        public override bool Equals(object obj)
        {
            return _value.Equals(obj);
        }

        public override string ToString()
        {
            return _value.ToString();
        }
    }

В классе 2 основных метода, на которые я возлагал свои надежды, это операторы неявного преобразования. Ведь я как наивный дурак предполагал, что DataTemplate будет преобразовывать объект в тот, который указан в свойстве DataType и всё будет прозрачно, точно так же как Nullable<T>. Но не тут то было.
Накидав пример
+
<Window x:Class="DataTemplateImplicit.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:dataTemplateImplicit="clr-namespace:DataTemplateImplicit"
        Title="MainWindow" Height="350" Width="525"
        DataContext="{StaticResource MainModel}">
    <Window.Resources>
        <DataTemplate x:Key="ItemTemplate" 
                      DataType="{x:Type dataTemplateImplicit:Person}">
            <UniformGrid Columns="2" Background="BurlyWood" Height="32" Margin="2">
                <TextBlock Text="{Binding Name}"/>
                <TextBlock Text="{Binding Age}"/>
            </UniformGrid>
        </DataTemplate>
    </Window.Resources>
    <UniformGrid Columns="3" >
        <ItemsControl ItemsSource="{Binding Persons}" ItemTemplate="{StaticResource ItemTemplate}"/>
        <ItemsControl ItemsSource="{Binding NullablePerson}" ItemTemplate="{StaticResource ItemTemplate}"/>
        <ItemsControl ItemsSource="{Binding CheckingPerson}" ItemTemplate="{StaticResource ItemTemplate}"/>
                      
    </UniformGrid>
</Window>

    public struct Person
    {
        public string Name { set; get; }
        public int Age { set; get; }
    }

    public class MainModel
    {
        public List<Person> Persons { set; get; }

        public List<Nullable<Person>> NullablePerson { set; get;}

        public List<CheckBoxWrapper<Person>> CheckingPerson { set; get; }

        public MainModel()
        {
            Persons = new List<Person>
            {
                new Person {Name = "Roman", Age = 32},
                new Person {Name = "Sofia", Age = 35},
                new Person {Name = "Olga", Age = 6},
                new Person {Name = "Sasha", Age = 14},
            };

            NullablePerson = new List<Person?>
            {
                Persons[0],
                null,
                Persons[1],
                null,
                Persons[2],
                null,
                Persons[3]
            };
            CheckingPerson = new List<CheckBoxWrapper<Person>>
            {
                Persons[0],
                Persons[1],
                Persons[2],
                Persons[3]
            };
        }
    }

я выяснил, что с Nullable всё работает, а с мои классом не работает. В чем грабли?
Ответ:
Сон Веры Павловны
Roman Mejtes
у меня есть переменная типа Type (указывающая на типа Class1), мне нужно получить объект этого типа, из объекта другого типа (Class2) в котором определен оператор implicit для для преобразования из Class2 в Class1. Как это сделать?

Только через рефлекшен, выдергивая у Class1 public static Class1 op_Implicit(Class2), потому как компилятор при преобразованиях через operator implicit/explicit вставляет в IL-код вызовы именно этих операторов:
namespace test
{
  class Program
  {
    static void Main(string[] args)
    {
      int n = 123;
      Test(n);
      Console.WriteLine("done");
      Console.ReadKey(true);
    }

    static void Test(Decimal d)
    {
      Console.WriteLine(d);
    }
  }
}

.method private hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint
  // Code size       32 (0x20)
  .maxstack  1
  .locals init ([0] int32 n)
  IL_0000:  ldc.i4.s   123
  IL_0002:  stloc.0
  IL_0003:  ldloc.0
  IL_0004:  call       valuetype [mscorlib]System.Decimal [mscorlib]System.Decimal::op_Implicit(int32)
  IL_0009:  call       void test.Program::Test(valuetype [mscorlib]System.Decimal)
  IL_000e:  ldstr      "done"
  IL_0013:  call       void [mscorlib]System.Console::WriteLine(string)
  IL_0018:  ldc.i4.1
  IL_0019:  call       valuetype [mscorlib]System.ConsoleKeyInfo [mscorlib]System.Console::ReadKey(bool)
  IL_001e:  pop
  IL_001f:  ret
} // end of method Program::Main

Ну, а поскольку биндинг работает через рефлекшн, но, видимо, не ориентируется на наличие операторов преобразования в типе, то и не вызывает эти операторы, а работает всё так же - просто по заданным в разметке свойствам, которых непосредственно у класса-враппера нет. Что же до Nullable<T> - это особый случай, у этого типа поддержка зашита глубоко на уровне CLR, и с ним преобразования работают. В частности, см. Рихтера по нюансы вызова GetType у Nullable<T>:
namespace test
{
  struct Foo {}
  class Program
  {
    static void Main(string[] args)
    {
      Console.WriteLine(new Nullable<Foo>(new Foo()).GetType().FullName);
      Console.ReadKey(true);
    }
  }
}

- в консольном выводе будет test.Foo.
А по поводу "облегчить жизнь" - я бы просто прикрутил IValueConverter, конвертящий из экземпляра враппера в нужный тип. Так действительно будет проще.

Спасибо большое, на счет op_Implicit Уже сам проникся, но отказался от всей этой идеи, запилил просто 2 шаблона и бог с ним, жаль, конечно, по сути получается, что DataType свойство особого смысла не имеет. Как я понял из кода DataTemplate, оно используется только в задании ключа ресурса (как TargetType) и для дизайнера.
Иногда WPF раздражающе негибок, особенно касательно Internal классов, свойств и методов. Которые охота переопределить, но возможности такой нет =( надеюсь когда нибудь мы увидим изменения в этом направлении, а то WPF последнее время вообще кое как обновляется.
Вопрос: как в design-time кинуть UserControl на форму и отредактировать?

Ctrl+V + Ctrl+V - копируются только контролы, расположенные на UserControl... а если выбираю в Toolbox созданный UserControl1 и пытаюсь его кинуть на форму получаю Failed to load toolbox item 'UserControl1'. It will be removed from the toolbox. (VS2015, Platform target установлен в Any CPU)
Ответ: FB Programmer, в Designer ни чего не делай, никогда (разве что при каком нибудь "крахе").

А так вот например:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class UserControl1: UserControl
    {
        public UserControl1()
        {
            InitializeComponent();
        }
        /// <summary>
        /// Не лучший пример и видеть сие свойство в дизайнере не надо, но в коде спокойно можно юзать
        /// </summary>
        [Browsable(false)]
        public Button Button1 { get { return button1; } }

        /// <summary>
        /// Текст для кнопки button1
        /// </summary>
        [Description("Текст для кнопки button1")]
        [Browsable(true)]
        public string Button1Caption { get { return button1.Text; } set { button1.Text = value; } }
...
Вопрос: BinaryReader.ReadBytes with PtrToStructure Все ли я правильно понимаю?

[quote ]BinaryReader.ReadBytes with PtrToStructure
public static TestStruct FromBinaryReaderBlock(BinaryReader br)
{
    //Read byte array
    byte[] buff = br.ReadBytes(Marshal.SizeOf(typeof(TestStruct)));

    //Make sure that the Garbage Collector doesn't move our buffer 
    GCHandle handle = GCHandle.Alloc(buff, GCHandleType.Pinned);

    //Marshal the bytes
    TestStruct s = (TestStruct)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(TestStruct));

    handle.Free();//Give control of the buffer back to the GC 
    return s;
}
[/quote]

Правильно ли я понимаю, что:
1 - метод Marshal.PtrToStructure вернул резльтат, который явным образом был приведен к типу структуры
2 - значение, уже приведенное к типу структуры, в виде структуры копируется (value, non-reference copy) в локальную переменную (s)?
Ответ:
автор
Таким делегатом может быть например алгоритм вычисления плавающей средней величины, которую невозможно вычислить только лишь из текущего элемента. Как следствие - такой делегат вынужден обращаться к исходной последовательности с тем, чтобы прочитать элементы в горизонте от текущего. В итоге количество обращений к элементам последовательности сильно возрастает (в N раз), и требования в части производительности к механизмам чтения элементов последовательности растут соответственно.
а нельзя заранее построить список делегатов, и на каждом шаге в соответствии со списком вычислять все необходимые им данные, а не скакать туда-сюда по последовательности?
Вопрос: Биндинг или DataContext для UserControl

У меня есть простенький UserControl:
Код XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<UserControl x:Class="SimpleMVVM.ViewModel.LibraryViewModel"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d">
    <Grid>
 
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
 
        <TextBox Text="{Binding Name}" />
    </Grid>
 
</UserControl>
Код C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
    public partial class LibraryViewModel
    {
        private string _name;
 
        public LibraryViewModel()
        {
            InitializeComponent();
            DataContext = this;
        }
 
        public string Name
        {
            get
            {
                return _name;
            }
            set
            {
                _name = value;
                OnPropertyChanged("_name");
            }
        }
    }
и есть главное окно MainWindow:
Код XML
1
2
3
4
5
6
7
8
9
10
11
12
<Window x:Class="SimpleMVVM.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:library="clr-namespace:SimpleMVVM.ViewModel">
 
    <StackPanel>
 
        <library:LibraryViewModel/>
 
    </StackPanel>
 
</Window>
Код C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
    public partial class MainWindow : Window
    {
        private readonly LibraryViewModel _libraryViewModel;
 
        public MainWindow()
        {
            InitializeComponent();
            _libraryViewModel = new LibraryViewModel();
            DataContext = this;
        }
 
        public LibraryViewModel LibraryViewModel
        {
            get
            {
                return _libraryViewModel;
            }
        }
    }
Внимание вопрос: как мне прибиндить (или задать DataContext) <library:LibraryViewModel/> к public LibraryViewModel LibraryViewModel?
Хочу писать что-то типа:
Код XML
1
<library:LibraryViewModel {Binding Path=LibraryViewModel} />
Сразу отвечу на вопрос: А зачем? Затем что у меня создается два объекта типа LibraryViewModel (первый внутри InitializeComponent(); и второй _libraryViewModel = new LibraryViewModel() и что к чему биндится непонятно.

Добавлено через 12 минут
То есть я хочу прибиндить не конкретную пропертю внутри UserControl к пропкртю внутри MainWindow, а прибиндить целый UserControl к соответствующему свойству внутри MainWindow (public LibraryViewModel LibraryViewModel в нашем случае). Либо задать для него DataContext.
Ответ: в MainWindow

Код XML
1
2
xmlns:libraryVM="clr-namespace:SimpleMVVM.ViewModel"
xmlns:libraryView="clr-namespace:SimpleMVVM.View"
Код XML
1
2
3
4
5
6
7
8
<Window.Resources>
    <DataTemplate DataType="{x:Type libraryVM:LibraryViewModel1}">
        <libraryView:Library1View />
    </DataTemplate>
    <DataTemplate DataType="{x:Type libraryVM:LibraryViewModel..}">
        <libraryView:Library..View />
    </DataTemplate>
</Window.Resources>
Вопрос: Различный контент для одного UserControl

Имеется 3 разных UserControl, у каждого свой ViewModel.
Имеется форма с кнопкой и панелькой.
При нажатии кнопки нужно в панельке отобразить тот или иной UserControl (тут предполагается что до нажатия я уже знаю какой UserControl должен отобразиться, нахожу с помощью кода, который выполняется во время загрузки формы). Предположим, что во всех ViewModel заложена некая константа принадлежности, по которой можно что-то привязывать.
Перегуглил много чего, но что-то запутался во всех этих DataTemplateSelector ...ContentPresenter
На основании вышесказанного, посоветуйте как сделать.
Ответ: Решение найдено. Нужно просто было убрать x:Key=".." в DataTemplate
Вопрос: UserControl с возможностю добавления в него других элементов

Собственно хоч создать свой UserControl, что-то на подобии ListView, ну что бы вот так можно было записать в xaml'е:

Код XML
1
2
3
4
    <local:MyListView Margin="10,34,10,10" Background="#FF202020">
        <local:MyListViewItem Background="#FF202020" />
        <local:MyListViewItem Background="#FF202020" />
    </local:MyListView>
Но мне пишет что мой контрол может содержать только один елемент внутри себя, типа "свойство 'Content' введено более одного раза"...

Вот код моего контрола:
Код XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<UserControl x:Class="MyUserControl.MyListView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:MyUserControl" 
             mc:Ignorable="d" >
    <UserControl.Resources>
        <Style TargetType="{x:Type local:MyListView}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type local:MyListView}">
                        <ScrollViewer Background="{TemplateBinding Background}"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="{TemplateBinding BorderThickness}">
                            <StackPanel x:Name="Controllers" Orientation="Vertical" HorizontalAlignment="Left">
                                <ContentPresenter Content="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Content}" />
                            </StackPanel>
                        </ScrollViewer>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </UserControl.Resources>
    <Grid>
    </Grid>
</UserControl>
Подскажите, как сделать так, что бы я мог добавлять свои итемы в MyListView контрол?
Что нужно изменить в моем UserControl'е, что бы он работал как Grid, и мог хранить в себе много елементов а не только один?
Ответ: novikov.ea, Да у меня именно такая цель и была, что б в моем 'local:MyListView' можно было отображать множество 'local:MyListViewItem' и только их, никакой другой тип.

На данный момент я реализовал прочто через наследование от ItemsControl, создание темплейта в его xaml'е и логики в кодбихайнде. Работает в принципе адекватно и запарился только с темплейтом ибо не сильно шарю в них.

Но вот все таки хочу понять как делать так как я хотел изначально. Прикол в том, что я уже имею UserControl, со всей логикой работы всех контролов на нем, короче готовый UserControl и вот я хотел именно его "всунуть" в 'local:MyListView', и я так понимаю это нужно использовать название класса этого контрола(который наследоватся от UserControl'а) как контейнер, правильно ли я понял, или нет?
Вопрос: Вывод элементов ItemsControl в UserControl

Добрый день. Имеется UserControl с ItemsControl внутри, который в свою очередь привязан к своему внутреннему DependencyProperty(SourceCollection) для биндинга из вне.

UserControl1:
XML
1
2
3
<ItemsControl ItemsSource="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}, Path=SourceCollection}">
...
</ItemsControl>
Window:
XML
1
<control:UserControl1 SourceCollection="{Binding Collection}"/>
Привязка работает, но не смог разобраться, как передать из Window какие данные надо выводить в ItemsControl. Хочется сделать автономный и независимый UserControl, который ничего не знает о данных из вне, а может принимать ссылку на коллекцию и каким-то образом понимать какие данные выводить(предположим строковое представление свойства элемента коллекции Name), но каким?

P.S. Не получилось правильно сформировать запрос в гугле, поэтому решился поинтересоваться у родного комьюнити
Ответ: Используйте . Создайте у UserControl свойство DisplayMemberPath типа string и привяжитесь к нему
XML
1
2
3
4
<ItemsControl ItemsSource="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}, Path=SourceCollection}"
              DisplayMemberPath="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}, Path=DisplayMemberPath}">
 
</ItemsControl>
XML
1
<control:UserControl1 SourceCollection="{Binding Collection}" DisplayMemberPath="Name"/>
Вопрос: Внутренняя проверка свойства в UserControl

Заморочился я сделать свой UserControl. Суть такова: контрол должен отражать числа double с тремя нулями после запятой. Имеет три открытых свойства: DoubleValue, MaxValue, MinValue.
Вот в чем загвоздка. Если DoubleValue не в промежутке между MinValue MaxValue, то контрол должен покраснеть или как-то еще показать, что значение не в диапазоне, без разницы. Вот как это правильно реализовать?

в xaml начал описывать вот так:
XML
1
2
3
4
5
6
7
8
9
10
11
<UserControl.Resources>
        <SolidColorBrush x:Key="BrushGreen" Color="#FF04FB04"/>
        <SolidColorBrush x:Key="BrushRed" Color="#FFFB0F04"/>
        
    </UserControl.Resources>
    
    <Grid>        
        <Rectangle x:Name="numberRect" Stroke="{DynamicResource BrushGreen}"></Rectangle>
        <TextBox Text="{Binding DoubleValue, ElementName=root, Mode=TwoWay, StringFormat=\{0:F3\}}" x:Name="NumberText" Margin="1"></TextBox>
    </Grid>
</UserControl>
в шарпе:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
public partial class NumberBox : UserControl
    {
        [Category("NumberBox")]
        [Browsable(true)]
        public double DoubleValue 
        {
            get { return (double)GetValue(ValueProperty); }
            set { 
                    SetValue(ValueProperty, value);                    
                }
        }
        [Category("NumberBox")]
        [Browsable(true)]
        public double MinValue {
            get { return (double)GetValue(MinValueProperty); }
            set { SetValue(MinValueProperty, value); }
        }
        [Category("NumberBox")]
        [Browsable(true)]
        public double MaxValue {
            get { return (double)GetValue(MaxValueProperty); }
            set { SetValue(MaxValueProperty, value); }
        }
 
 
        public static readonly DependencyProperty ValueProperty = DependencyProperty.Register("DoubleValue", typeof(double), typeof(NumberBox));
        public static readonly DependencyProperty MinValueProperty = DependencyProperty.Register("MinValue", typeof(double), typeof(NumberBox));
        public static readonly DependencyProperty MaxValueProperty = DependencyProperty.Register("MaxValue", typeof(double), typeof(NumberBox));
 
        public NumberBox()
        {
            InitializeComponent();
        }
 
        
    }
Вот как-то не могу понять, как лучше сделать проверку, триггером в xaml или писать функцию в шарпе.

Вариант сделать через ControlTemplate и не заморачиваться через UserControl тоже рассматриваю.
Ответ: Сначала выбираем инжектор, любой из списка. После этого типа все там должно заработать. У нас на вкладке АН расчетный зазор сразу в красной рамке, и это правильно, ибо рядом подсказка каким он должен быть. Для первой форсунки в списке - 0,054 мм

1. Вкладка АН
1.1 Измерение №1 ставим 0,05
1.2 Измерение №2 ставим 1,0
1.3 Измерение №3 ставим 1,054. Расчетный зазор становится без красной рамки и показывает нужную циферку.
1.4 Меняем Измерение №3 и видим как красиво становится красным расчетный зазор, когда значение выходит за рамки.
1.5 Переходим на вкладку AHR, возвращаемся назад и уже ничего не работает. Примерно тоже самое на вкладке AHR. Только там краснеть должно Измерение №1

Добавлено через 11 минут
Вот, если работает, то переходим на вкладку AHR. Ставим Измерение №1 - 0,5 Измерение №2 - 1,0 и уже не работает на вкладке AH