WPF 도움되는 정보
- Drag Dropping from WPF to Notepad
- How do I set a cookie on HttpClient’s HttpRequestMessage
- UserControl
- Thumb 컨트롤의 DragDelta 사용법
- 볼륨 컨트롤
- MVVM 기본 코드
1. Drag Dropping from WPF to Notepad
https://stackoverflow.com/questions/13308745/drag-dropping-from-wpf-to-notepad
private void listView1_MouseMove(object sender, MouseEventArgs e)
{
try
{
if (e.LeftButton == MouseButtonState.Released)
{
alreadycopying = false;
}
if (e.LeftButton == MouseButtonState.Pressed && alreadycopying == false)
{
alreadycopying = true;
System.IO.StreamWriter test = new System.IO.StreamWriter(@"C:\SuperSecretTestFile.txt");
test.WriteLine("Test");
test.Close();
List<String> testlist = new List<string>();
testlist.Add(@"C:\SuperSecretTestFile.txt");
DataObject d = new DataObject();
d.SetData(DataFormats.FileDrop, testlist.ToArray<string>());
DragDrop.DoDragDrop(listView1, d, DragDropEffects.All);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
2. How do I set a cookie on HttpClient’s HttpRequestMessage
https://stackoverflow.com/questions/12373738/how-do-i-set-a-cookie-on-httpclients-httprequestmessage
https://d-fens.ch/2016/12/27/howto-set-cookie-header-on-defaultrequestheaders-of-httpclient/
The accepted answer is the correct way to do this in most cases. However, there are some situations where you want to set the cookie header manually. Normally if you set a “Cookie” header it is ignored, but that’s because HttpClientHandler defaults to using its CookieContainer property for cookies. If you disable that then by setting UseCookies to false you can set cookie headers manually and they will appear in the request, e.g.
using (var httpClient = new HttpClient(new HttpClientHandler { UseCookies = false }))
{
var uri = new Uri("http://www.example.com");
httpClient.BaseAddress = uri;
httpClient.DefaultRequestHeaders.Add("Cookie", "auth=ArbitrarySessionToken");
var response = httpClient.GetAsync(uri).Result;
}
3. UserControl
using System.Windows;
using System.Windows.Controls;
namespace WpfApp1.UserControls
{
public partial class MyControl : UserControl
{
public MyControl()
{
InitializeComponent();
}
public static readonly DependencyProperty AddressProperty =
DependencyProperty.Register(
"Address",
typeof(string),
typeof(MyControl),
new FrameworkPropertyMetadata(
string.Empty,
new PropertyChangedCallback(OnAddressChanged), // 2번
new CoerceValueCallback(CoerceValue))); // 1번
public string Address
{
get { return (string)GetValue(AddressProperty); }
set { SetValue(AddressProperty, value); }
}
// 1번. 데이터를 검사해서 수정할 수 있다.
private static object CoerceValue(DependencyObject element, object value)
{
string newValue = (string)value;
MyControl control = (MyControl)element;
return newValue;
}
// 2번. 값이 변경될 때 발생 (CoerceValueCallback 후에 발생)
private static void OnAddressChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
{
MyControl control = (MyControl)obj;
RoutedPropertyChangedEventArgs<string> e = new RoutedPropertyChangedEventArgs<string>(
(string)args.OldValue,
(string)args.NewValue,
AddressChangedEvent);
// 아래 RoutedEvent 이벤트 핸들러 호출
control.OnValueChanged(e);
}
public static readonly RoutedEvent AddressChangedEvent = EventManager.RegisterRoutedEvent(
"AddressChanged",
RoutingStrategy.Bubble,
typeof(RoutedPropertyChangedEventHandler<string>),
typeof(MyControl));
public event RoutedPropertyChangedEventHandler<string> AddressChanged
{
add { AddHandler(AddressChangedEvent, value); }
remove { RemoveHandler(AddressChangedEvent, value); }
}
protected virtual void OnValueChanged(RoutedPropertyChangedEventArgs<string> args)
{
RaiseEvent(args);
}
}
}
4. Thumb 컨트롤의 DragDelta 사용법
# How to: Resize a Canvas by Using a Thumb
https://learn.microsoft.com/en-us/dotnet/desktop/wpf/controls/how-to-resize-a-canvas-by-using-a-thumb?view=netframeworkdesktop-4.8&viewFallbackFrom=netdesktop-6.0
# Using the Thumb Control to Drag Objects on a Canvas
https://wpf.2000things.com/2012/12/19/715-using-the-thumb-control-to-drag-objects-on-a-canvas/
# C# WPF MVVM Control Move X,Y 제어 – Interface 기초강좌 | ItemsControl Canvas Thumb
https://www.youtube.com/watch?v=ZgoCBvtoSpE
<Canvas x:Name="canvas1">
<Thumb Canvas.Left="100" Canvas.Top="60" DragDelta="Thumb_DragDelta" DragStarted="onDragStarted" DragCompleted="onDragCompleted">
<Thumb.Template>
<ControlTemplate>
<StackPanel x:Name="sp1">
<Ellipse x:Name="el1" Width="100" Height="100" StrokeThickness="5" Stroke="Blue" Fill="AliceBlue"/>
<TextBlock x:Name="textblock1" Text="X:"/>
<TextBlock x:Name="textblock2" Text="Y:"/>
</StackPanel>
</ControlTemplate>
</Thumb.Template>
</Thumb>
</Canvas>
---------------------------------------------------------------------------------------------------------------------------------------------------
private void Thumb_DragDelta(object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e)
{
var thumb = e.Source as Thumb;
if ((Canvas.GetLeft(thumb) + e.HorizontalChange) > -1 && (Canvas.GetLeft(thumb) + e.HorizontalChange + 99) < canvas1.ActualWidth)
Canvas.SetLeft(thumb, Canvas.GetLeft(thumb) + e.HorizontalChange);
if ((Canvas.GetTop(thumb) + e.VerticalChange) > -1 && (Canvas.GetTop(thumb) + e.VerticalChange + 100) < canvas1.ActualHeight - 35)
Canvas.SetTop(thumb, Canvas.GetTop(thumb) + e.VerticalChange);
TextBlock c1 = (TextBlock)thumb!.Template.FindName("textblock1", thumb);
TextBlock c2 = (TextBlock)thumb!.Template.FindName("textblock2", thumb);
c1.Text = "X: " + Canvas.GetLeft(thumb).ToString();
c2.Text = "Y: " + Canvas.GetTop(thumb).ToString();
}
void onDragStarted(object sender, DragStartedEventArgs e)
{
var thumb = e.Source as Thumb;
var e1 = (Ellipse)thumb!.Template.FindName("el1", thumb);
e1.Fill = Brushes.Orange;
}
void onDragCompleted(object sender, DragCompletedEventArgs e)
{
var thumb = e.Source as Thumb;
var e1 = (Ellipse)thumb!.Template.FindName("el1", thumb);
e1.Fill = Brushes.Aqua;
}
5. 볼륨 컨트롤
https://stackoverflow.com/questions/13139181/how-to-programmatically-set-the-system-volume
# CoreAudio 라이브러리
using AudioSwitcher.AudioApi.CoreAudio;
CoreAudioDevice defaultPlaybackDevice = new CoreAudioController().DefaultPlaybackDevice;
Debug.WriteLine("Current Volume:" + defaultPlaybackDevice.Volume);
defaultPlaybackDevice.Volume = 80;
------------------------------------------------------------------------------------------
CoreAudioDevice defaultPlaybackDevice = new CoreAudioController().DefaultPlaybackDevice;
double vol = defaultPlaybackDevice.Volume;
defaultPlaybackDevice.Volume = defaultPlaybackDevice.Volume - 5.0;
defaultPlaybackDevice.Volume = defaultPlaybackDevice.Volume + 5.0;
https://www.nuget.org/packages/AudioSwitcher.AudioApi.CoreAudio/
# Windows API
IntPtr windowHandle = new WindowInteropHelper(Application.Current.MainWindow).EnsureHandle();
private const int APPCOMMAND_VOLUME_MUTE = 0x80000;
private const int APPCOMMAND_VOLUME_UP = 0xA0000;
private const int APPCOMMAND_VOLUME_DOWN = 0x90000;
private const int WM_APPCOMMAND = 0x319;
[DllImport("user32.dll")]
public static extern IntPtr SendMessageW(IntPtr hWnd, int Msg,
IntPtr wParam, IntPtr lParam);
private void Mute()
{
SendMessageW(windowHandle, WM_APPCOMMAND, windowHandle,
(IntPtr)APPCOMMAND_VOLUME_MUTE);
}
private void VolDown()
{
SendMessageW(windowHandle, WM_APPCOMMAND, windowHandle,
(IntPtr)APPCOMMAND_VOLUME_DOWN);
}
private void VolUp()
{
SendMessageW(windowHandle, WM_APPCOMMAND, windowHandle,
(IntPtr)APPCOMMAND_VOLUME_UP);
}
# keybd_event 함수
private const byte VK_VOLUME_MUTE = 0xAD;
private const byte VK_VOLUME_DOWN = 0xAE;
private const byte VK_VOLUME_UP = 0xAF;
[DllImport("user32.dll")]
static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, int dwExtraInfo);
keybd_event(VK_VOLUME_UP, 0, 0, 0); // increase volume
keybd_event(VK_VOLUME_DOWN, 0, 0, 0); // decrease volume
6. MVVM 기본 코드
# BaseViewModel.cs
public class BaseViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler? PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string? name = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
}
# MainViewModel.cs
public class MainViewModel : BaseViewModel
{
private bool _isBusy;
public bool IsBusy
{
get => _isBusy;
set
{
if (_isBusy == value)
return;
_isBusy = value;
OnPropertyChanged(); // CallerMemberName 속성으로 인자 생략 가능
}
}
public RelayCommand MyCommand { get; }
private void My(object obj)
{
}
public MainViewModel()
{
MyCommand = new RelayCommand(x => My(x), y => !IsBusy);
}
}
# RelayCommand.cs
public class RelayCommand : ICommand
{
#region Fields
private readonly Action<object> _execute;
private readonly Predicate<object> _canExecute;
#endregion // Fields
#region Constructors
public RelayCommand(Action<object> execute) : this(execute, _ => true) { }
public RelayCommand(Action<object> execute, Predicate<object> canExecute)
{
_execute = execute;
_canExecute = canExecute;
}
#endregion // Constructors
#region ICommand Members
[DebuggerStepThrough]
public bool CanExecute(object? parameter)
{
return _canExecute(parameter!);
}
public event EventHandler? CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public void Execute(object? parameter)
{
_execute(parameter!);
}
public void Refresh()
{
CommandManager.InvalidateRequerySuggested();
}
#endregion // ICommand Members
}