it-source

코드백에 정의된 바인딩 개체

criticalcode 2023. 4. 26. 23:24
반응형

코드백에 정의된 바인딩 개체

예를 들어, XAML은 window.xaml.cs 내에서 window.xamland라는 코드 뒤에 인스턴스화된 개체가 있습니다.

protected Dictionary<string, myClass> myDictionary;

XAML 마크업만 사용하여 이 개체를 예를 들어 목록 보기에 바인딩하려면 어떻게 해야 합니까?

업데이트:

(이것이 바로 내 테스트 코드에 있는 내용입니다):

<Window x:Class="QuizBee.Host.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="{Binding windowname}" Height="300" Width="300"
    DataContext="{Binding RelativeSource={RelativeSource Self}}">
    <Grid>
    </Grid>
</Window>

그리고 뒤에 있는 코드에서는

public partial class Window1 : Window
{
    public const string windowname = "ABCDEFG";

    public Window1()
    {
        InitializeComponent();
    }
}

제목이 "ABCDEFG"가 되어야 한다고 가정합니다. 하지만 결국 아무것도 표시되지 않습니다.

훨씬 더 쉬운 방법이 있습니다.창 또는 사용자 컨트롤에 이름을 할당한 다음 요소 이름으로 바인딩할 수 있습니다.

창 1.xaml

<Window x:Class="QuizBee.Host.Window1"
        x:Name="Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <ListView ItemsSource="{Binding ElementName=Window1, Path=myDictionary}" />
</Window>

Window1.xaml.cs

public partial class Window1:Window
{
    // the property must be public, and it must have a getter & setter
    public Dictionary<string, myClass> myDictionary { get; set; }

    public Window1()
    {
        // define the dictionary items in the constructor
        // do the defining BEFORE the InitializeComponent();

        myDictionary = new Dictionary<string, myClass>()
        {
            {"item 1", new myClass(1)},
            {"item 2", new myClass(2)},
            {"item 3", new myClass(3)},
            {"item 4", new myClass(4)},
            {"item 5", new myClass(5)},
        }; 

        InitializeComponent();
    }
}

컨트롤, 폼 등에 대한 데이터 컨텍스트를 다음과 같이 설정할 수 있습니다.

DataContext="{Binding RelativeSource={RelativeSource Self}}"

명확화:

위의 값으로 설정되는 데이터 컨텍스트는 코드 뒤에 있는 "소유" 요소에서 수행되어야 합니다. 따라서 Window의 경우 Window 선언에서 설정해야 합니다.

이 코드로 작업하는 예제가 있습니다.

<Window x:Class="MyClass"
  Title="{Binding windowname}"
  DataContext="{Binding RelativeSource={RelativeSource Self}}"
  Height="470" Width="626">

그러면 이 수준에서 설정된 DataContext는 하위 요소에 대해 명시적으로 변경하지 않는 한 창의 모든 요소에 의해 상속되므로, 창에 대한 DataContext를 설정한 후에는 창의 모든 컨트롤에서 CodeBeynd 속성에 대한 직접 바인딩만 수행할 수 있습니다.

Guy의 대답은 정확하지만(아마도 10건 중 9건은 맞을 것입니다), DataContext를 다시 설정할 때 이미 스택을 설정한 컨트롤에서 이 작업을 시도하는 경우에는 DataContext를 재설정할 수 있습니다.

DataContext="{Binding RelativeSource={RelativeSource Self}}"

그러면 당연히 기존 바인딩이 해제됩니다.

이 경우 부모가 아닌 바인딩하려는 컨트롤에 RelativeSource를 설정해야 합니다.

즉, UserControl 속성에 바인딩하는 경우:

Binding Path=PropertyName, 
        RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}

현재 데이터 바인딩에서 어떤 일이 발생하는지 확인하는 것이 얼마나 어려울 수 있는지를 고려할 때, 해당 설정을 발견하더라도 이 점을 염두에 둘 필요가 있습니다.RelativeSource={RelativeSource Self}현재 작동합니다 :)

좀 더 명확하게 설명하겠습니다.'get','set'이 없는 속성은 바인딩할 수 없습니다.

저는 그 질문자의 경우와 마찬가지로 그 사건에 직면해 있습니다.그리고 바인딩이 제대로 작동하려면 다음과 같은 것들이 있어야 합니다.

//(1) Declare a property with 'get','set' in code behind
public partial class my_class:Window {
  public String My_Property { get; set; }
  ...

//(2) Initialise the property in constructor of code behind
public partial class my_class:Window {
  ...
  public my_class() {
     My_Property = "my-string-value";
     InitializeComponent();
  }

//(3) Set data context in window xaml and specify a binding
<Window ...
DataContext="{Binding RelativeSource={RelativeSource Self}}">
  <TextBlock Text="{Binding My_Property}"/>
</Window>

코드 뒤에 있는 창의 DataContext를 사전으로 설정합니다.XAML에는 다음과 같이 쓸 수 있습니다.

<ListView ItemsSource="{Binding}" />

그러면 ListView가 사전에 바인딩됩니다.

더 복잡한 시나리오의 경우 MVVM 패턴 뒤에 있는 기술의 하위 집합이 됩니다.

한 가지 방법은 관찰 가능한 컬렉션(시스템)을 만드는 것입니다.컬렉션.개체 모델) 및 사전 데이터가 들어 있습니다.그런 다음 관찰 가능한 컬렉션을 목록 상자에 바인딩할 수 있습니다.

XAML에는 다음과 같은 것이 있어야 합니다.

<ListBox ItemsSource="{Binding Path=Name_of_your_ObservableCollection" />

컨버터 정의:

public class RowIndexConverter : IValueConverter
{
    public object Convert( object value, Type targetType,
                           object parameter, CultureInfo culture )
    {
        var row = (IDictionary<string, object>) value;
        var key = (string) parameter;
        return row.Keys.Contains( key ) ? row[ key ] : null;
    }

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

사전의 사용자 정의 정의에 바인딩합니다.제가 생략한 재정의가 많지만 인덱서는 값이 변경될 때 속성 변경 이벤트를 발생시키기 때문에 중요합니다.소스와 대상 바인딩에 필요합니다.

public class BindableRow : INotifyPropertyChanged, IDictionary<string, object>
{
    private Dictionary<string, object> _data = new Dictionary<string, object>( );

    public object Dummy   // Provides a dummy property for the column to bind to
    {
        get
        {
            return this;
        }
        set
        {
            var o = value;
        }
    }


    public object this[ string index ]
    {
        get
        {
            return _data[ index ];
        }
        set
        {
            _data[ index ] = value;
            InvokePropertyChanged( new PropertyChangedEventArgs( "Dummy" ) ); // Trigger update
        }
    }


}

.xaml 파일에서 이 변환기를 사용합니다.첫 번째 참조:

<UserControl.Resources>
    <ViewModelHelpers:RowIndexConverter x:Key="RowIndexConverter"/>
</UserControl.Resources>

그런 다음, 예를 들어 사전에 키가 "이름"인 항목이 있는 경우, 이 항목에 바인딩하려면 다음을 사용합니다.

<TextBlock  Text="{Binding Dummy, Converter={StaticResource RowIndexConverter}, ConverterParameter=Name}">

속성 "창 이름"을 종속성 속성으로 만들고 나머지는 그대로 유지합니다.

저도 똑같은 문제를 겪고 있었지만 제 문제는 제가 지역 변수를 설정했기 때문이 아니었습니다.저는 하위 창에 있었고, 방금 윈도우 XAML에 추가한 상대적인 데이터 컨텍스트를 설정해야 했습니다.

<Window x:Class="Log4Net_Viewer.LogItemWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    DataContext="{Binding RelativeSource={RelativeSource Self}}"
    Title="LogItemWindow" Height="397" Width="572">

당신은 x:참조 트릭을 시도할 수 있습니다.

<Window ... x:Name="myWindow"><ListBox ItemsSource="{Binding Items, Source={x:Reference myWindow}}" /></Window>

뒤에 있는 코드에 참조).DataTemplateSelector)

public partial class MainWindow : Window
{
  public MainWindow()
  {
    this.DataTemplateSelector = new MyDataTemplateSelector();

    InitializeComponent();

    // ... more initializations ...
  }

  public DataTemplateSelector DataTemplateSelector { get; }

  // ... more code stuff ...
}

XAML은 XAML로 됩니다.RelativeSource선조들을 통해 다음을 포함할 때까지.Window그래서 나는 나의Window하고 래스를자사용합다니산을고를 통해 합니다.Path선언:

<GridViewColumn Header="Value(s)"
                CellTemplateSelector="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataTemplateSelector}"/>

성정 설속DataTemplateSelector하기 InitializeComponent는 의구누락따달니다라집의 누락에 .IPropertyChanged 또는 사용의구와 DependencyProperty 시 되지 않습니다. ㅠㅠㅠㅠㅠㅠㅠㅠㅠㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜDataTemplateSelector.

언급URL : https://stackoverflow.com/questions/1705322/binding-objects-defined-in-code-behind

반응형