2012-01-07 2 views
6

WPF가 때때로 격노 할 수 있습니다.WPF 창과 사용자 컨트롤간에 데이터를 공유하는 가장 좋은 방법은 무엇입니까?

나는 탭 컨트롤과 여러 탭이 포함 된 단일 기본 창으로 구성된 매우 간단한 응용 프로그램을 가지고 있습니다. 같은 파일에 모든 탭에 대한 코드가 있다는 아이디어가 마음에 들지 않았으므로 this question의 대답을 사용하여 각 탭을 개별 사용자 컨트롤로 분리했습니다.

내 기본 창에는 응용 프로그램 설정 및 기타 응용 프로그램 전체 데이터가 포함 된 개체의 인스턴스가 있습니다. 여러 탭에서 데이터 바인딩을 위해이 데이터에 액세스해야합니다. 나는 이것을 달성하기위한 좋은 방법을 찾을 수 없었습니다.

먼저 컨트롤 Loaded 이벤트의 부모 창에 액세스하려고 시도하고 아래 코드와 같이 설정 개체가 노출 된 기본 창에서 속성에 대한 참조를 가져 오려고했습니다. 이러한 종류의 작업은 탭에 포커스가 올 때마다로드 된 이벤트가 발생하는 것을 제외하고는 작동합니다. 또한이 이벤트는 컨트롤 수명주기의 후반에 발생하므로 사용자 컨트롤 XAML에서이 개체의 속성 중 하나에 바인딩 할 수 없습니다.

private void MyUserControl_Loaded(object sender, RoutedEventArgs e) 
{ 
    this.ApplicationSettings = ((MainWindow)Window.GetWindow(this)).ApplicationSettings; 
} 

은 그 때 나는 사용자 정의 컨트롤의 생성자에 데이터를 전달하는 실험을하지만, XAML에서 그렇게 할 수있는 방법은 없습니다.

이것은 응용 프로그램 전반의 설정이므로 ApplicationSettings 클래스를 싱글 톤으로 만들고 어디서나 참조 할 수 있지만 단위 테스트 목적으로는 사용하지 않는 것이 좋습니다.

그러면 어떻게 이런 식으로 끝낼 수 있습니까? 내 접근법에 근본적인 결함이 있습니까? 내 마음 속에는 이러한 모든 UI 요소가 동일한 창에 포함되어 있으므로 주 창에서 데이터에 액세스 할 수 있어야하지만 개체 모델은이를 허용하지 않습니다.

답변

2

이 예에서 (래퍼 클래스의 정적 속성으로 설정 개체 SettingsHolder을 넣어 XAML에

를 통해 다양한 그것을 응용 프로그램을 참조 할 수 있습니다 : 네임 스페이스 당신의 SettingsHolder되는 local

{Binding SettingName, Source={x:Static local:SettingsHolder.Settings}} 

클래스에 코드에서

:.

var x = SettingsHolder.Settings.SettingName; 
SettingsHolder.Settings.SettingName = x; 
+0

이것이 내가 취할 수있는 길이라고 생각합니다. 원래 게시물에서 말했듯이, 나는 실제 싱글 톤없이 싱글 톤 동작을 원한다. 사실, 아마도 클래스 싱글 톤을 만들지 만, 테스트 목적으로 생성자를 public으로 두십시오. 감사합니다. – EricTheRed

1

사용자 정의 컨트롤의 선언에서 데이터 컨텍스트를 바인딩해야하는 모든 항목이 들어있는 개체의 인스턴스로 설정할 수 있습니다! 즉 평소처럼 사용자 컨트롤 내에서 '인스턴스를 객체의

<someNamespace:EricsUserControl DataContext="{Binding InstanceOfBindingObject}"/>

그런 다음 속성에 액세스 할 수 있습니다.

+0

이것은 정말 좋은 점입니다. 다른 용도로 사용할 수는 있지만 코드의 설정에 액세스 할 수 있도록 옵션을 열어두고 싶습니다. – EricTheRed

+0

@EricTheRed 완벽하게 감지 할 수 있지만 머리를 위로하면 코드 내의 사용자 정의 컨트롤에 대한 DataContext에 액세스 할 수 있습니다. 따라서 위와 같이 인스턴스 객체에 바인딩 한 다음 코드 숨김 파일에서 'var myInstance = (BindingObjectClass) this.DataContext'라는 코드를 약간 사용하면 myInstance 변수에서 해당 객체에 액세스 할 수 있습니다! 희망은 언젠가는 미래에 도움이됩니다! – Kevek

0

내가하는 것은 TabFrame을 사용하고 FramePage을 넣는 것입니다. (하지만 나는 User Control에 적용 할 수 있다고 생각한다). 생성자는 페이지가 생성 될 때만 시작되며 페이지가 생성 된 시점을 제어 할 수 있으며 생성자에서 정보를 전달할 수 있습니다. 페이지에는 더 많은 라이프 사이클 이벤트가 있습니다. 또한 UI를 빌드하는 데 Loaded 이벤트를 사용합니다 (한 번 실행). XAML에서 페이지를 바인딩하면 응용 프로그램을 시작할 때 해당 페이지가 실행되고 정보를 전달할 수 없습니다. 이것은 페이지를 생성하여 대화 상자에 표시하지만 해당 페이지를 프레임에 바인딩 할 수 있습니다.

내가 이해하지 못하는 페이지에서 수명주기를 얻는 경우가 있다는 것을 솔직하게 말할 필요가 있습니다. 소금 한 알을 가지고 이것을 섭취하십시오. 그러나 요점은 당신에게 필요한 것을 줄 수있는 생성자와로드 된 이벤트가 있다는 것입니다.

+0

그건 영리한거야! 나는 그런 식으로 생각하지 않았다. 나는 그러나 내가 일하고있는 것을 생각한다. 이것은 약간 과잉이다. 생각에 감사드립니다. – EricTheRed

관련 문제